summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorService qcabuildsw <qcabuildsw@localhost>2016-09-10 12:14:04 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-10 12:14:04 -0700
commitaa95906d2ee5ed85b1774e8f753c8c950d9e2d83 (patch)
treefff459eedb0fcc28739fde6ca5ad83d5228a6937
parent3a01837e03fc7f27e422b445c4aecb0132801551 (diff)
parent1481aff5624e9c32651c8612a8ba4ac40ce07708 (diff)
Merge "qcacld-3.0: Add multi-queue NAPI function" into wlan-cld3.driver.lnx.1.1-dev
-rw-r--r--Kbuild1
-rw-r--r--core/hdd/inc/wlan_hdd_napi.h27
-rw-r--r--core/hdd/src/wlan_hdd_main.c3
-rw-r--r--core/hdd/src/wlan_hdd_napi.c81
4 files changed, 98 insertions, 14 deletions
diff --git a/Kbuild b/Kbuild
index 0e4db79eca49..54e4eadedc49 100644
--- a/Kbuild
+++ b/Kbuild
@@ -865,6 +865,7 @@ HIF_SDIO_NATIVE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR)/hif.o \
ifeq ($(CONFIG_WLAN_NAPI), y)
HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_napi.o
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_napi_cpu.o
endif
HIF_PCIE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_PCIE_DIR)/if_pci.o
diff --git a/core/hdd/inc/wlan_hdd_napi.h b/core/hdd/inc/wlan_hdd_napi.h
index f4bfa75f169a..9ea15773e72a 100644
--- a/core/hdd/inc/wlan_hdd_napi.h
+++ b/core/hdd/inc/wlan_hdd_napi.h
@@ -37,9 +37,12 @@
/* CLD headers */
#include "hif_napi.h"
+
/* Linux headers */
#include <linux/netdevice.h> /* net_device */
+struct hdd_context_s;
+
#define HDD_NAPI_ANY (-1)
int hdd_napi_enabled(int id);
@@ -58,6 +61,18 @@ int hdd_napi_poll(struct napi_struct *napi, int budget);
struct qca_napi_data *hdd_napi_get_all(void);
+#ifdef HELIUMPLUS
+int hdd_napi_apply_throughput_policy(struct hdd_context_s *hddctx,
+ uint64_t tx_packets,
+ uint64_t rx_packets);
+#else /* FEATURE_NAPI and NOT HELIUM */
+static inline int hdd_napi_apply_throughput_policy(struct hdd_context_s *,
+ uint64_t, uint64_t)
+{
+ return 0;
+}
+#endif /* HELIUMPLUS */
+
#else /* ! defined(FEATURE_NAPI) */
#include "hif_napi.h"
/**
@@ -71,11 +86,17 @@ static inline int hdd_napi_enabled(int id) { return 0; }
static inline int hdd_napi_create(void) { return 0; }
static inline int hdd_napi_destroy(int force) { return 0; }
static inline int hdd_napi_stats(char *buf, int max, char *indp,
- struct qca_napi_data *napid)
-{ return 0; }
+ struct qca_napi_data *napid) { return 0; }
static inline int hdd_napi_event(enum qca_napi_event event, void *data)
-{ return 0; }
+{
+ return 0;
+}
static inline struct qca_napi_data *hdd_napi_get_all(void) { return NULL; }
+static inline int hdd_napi_apply_throughput_policy(struct hdd_context_s *,
+ uint64_t, uint64_t)
+{
+ return 0;
+}
#endif /* FEATURE_NAPI */
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 8bbe09acc521..77e255873f65 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -110,6 +110,7 @@
#include "ol_rx_fwd.h"
#include "wlan_hdd_lpass.h"
#include "nan_api.h"
+#include <wlan_hdd_napi.h>
#ifdef MODULE
#define WLAN_MODULE_NAME module_name(THIS_MODULE)
@@ -4894,7 +4895,6 @@ void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx,
enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
-
if (total > hdd_ctx->config->busBandwidthHighThreshold)
next_vote_level = PLD_BUS_WIDTH_HIGH;
else if (total > hdd_ctx->config->busBandwidthMediumThreshold)
@@ -4928,6 +4928,7 @@ void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx,
if (cds_sched_handle_throughput_req(true))
hdd_err("high bandwidth set rx affinity fail");
}
+ hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, rx_packets);
}
/* fine-tuning parameters for RX Flows */
diff --git a/core/hdd/src/wlan_hdd_napi.c b/core/hdd/src/wlan_hdd_napi.c
index 2706b71037e1..4d4941a07dcf 100644
--- a/core/hdd/src/wlan_hdd_napi.c
+++ b/core/hdd/src/wlan_hdd_napi.c
@@ -105,6 +105,7 @@ int hdd_napi_create(void)
{
struct hif_opaque_softc *hif_ctx;
int rc = 0;
+ hdd_context_t *hdd_ctx;
NAPI_DEBUG("-->");
@@ -116,11 +117,20 @@ int hdd_napi_create(void)
rc = hif_napi_create(hif_ctx, hdd_napi_poll,
QCA_NAPI_BUDGET,
QCA_NAPI_DEF_SCALE);
- if (rc < 0)
+ if (rc < 0) {
hdd_err("ERR(%d) creating NAPI instances",
rc);
- else
+ } else {
hdd_info("napi instances were created. Map=0x%x", rc);
+ hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+ if (unlikely(NULL == hdd_ctx)) {
+ QDF_ASSERT( 0 );
+ rc = -EFAULT;
+ } else {
+ rc = hdd_napi_event(NAPI_EVT_INI_FILE,
+ (void *)hdd_ctx->napi_enable);
+ }
+ }
}
NAPI_DEBUG("<-- [rc=%d]", rc);
@@ -204,20 +214,16 @@ int hdd_napi_enabled(int id)
}
/**
- * hdd_napi_event() - relay the event detected by HDD to HIF NAPI decision maker
+ * hdd_napi_event() - relay the event detected by HDD to HIF NAPI event handler
* @event: event code
* @data : event-specific auxiliary data
*
- * Return code does not indicate a change, but whether or not NAPI is
- * enabled at the time of the return of the function. That is, if NAPI
- * was disabled before the call, and the event does not cause NAPI to be
- * enabled, a value of 0 will be returned indicating that it is (still)
- * disabled.
+ * See function documentation in hif_napi.c::hif_napi_event for list of events
+ * and how each of them is handled.
*
* Return:
* < 0: error code
- * = 0: NAPI state = disabled (after processing the event)
- * = 1: NAPI state = enabled (after processing the event)
+ * = 0: event handled successfully
*/
int hdd_napi_event(enum qca_napi_event event, void *data)
{
@@ -236,6 +242,61 @@ int hdd_napi_event(enum qca_napi_event event, void *data)
return rc;
}
+#ifdef HELIUMPLUS
+/**
+ * hdd_napi_apply_throughput_policy() - implement the throughput action policy
+ * @hddctx: HDD context
+ * @tx_packets: number of tx packets in the last interval
+ * @rx_packets: number of rx packets in the last interval
+ *
+ * Called by hdd_bus_bw_compute_cb, checks the number of packets in the last
+ * interval, and determines the desired napi throughput state (HI/LO). If
+ * the desired state is different from the current, then it invokes the
+ * event handler to switch to the desired state.
+ *
+ * The policy implementation is limited to this function and
+ * The current policy is: determine the NAPI mode based on the condition:
+ * (total number of packets > medium threshold)
+ * - tx packets are included because:
+ * a- tx-completions arrive at one of the rx CEs
+ * b- in TCP, a lof of TX implies ~(tx/2) rx (ACKs)
+ * c- so that we can use the same normalized criteria in ini file
+ * - medium-threshold (default: 500 packets / 10 ms), because
+ * we would like to be more reactive.
+ *
+ * Return: 0 : no action taken, or action return code
+ * !0: error, or action error code
+ */
+int hdd_napi_apply_throughput_policy(struct hdd_context_s *hddctx,
+ uint64_t tx_packets,
+ uint64_t rx_packets)
+{
+ int rc = 0;
+ uint64_t packets = tx_packets + rx_packets;
+ enum qca_napi_tput_state req_state;
+ struct qca_napi_data *napid = hdd_napi_get_all();
+ int enabled;
+
+ NAPI_DEBUG("-->%s(tx=%lld, rx=%lld)", __func__, tx_packets, rx_packets);
+
+ if ((napid != NULL) &&
+ (enabled = hdd_napi_enabled(HDD_NAPI_ANY))) {
+ if (packets > hddctx->config->busBandwidthHighThreshold)
+ req_state = QCA_NAPI_TPUT_HI;
+ else
+ req_state = QCA_NAPI_TPUT_LO;
+
+ if (req_state != napid->napi_mode)
+ rc = hdd_napi_event(NAPI_EVT_TPUT_STATE,
+ (void *)req_state);
+ } else {
+ hdd_err("ERR: napid (%p) NULL or napi_enabled (%d) FALSE",
+ napid, enabled);
+ }
+ return rc;
+}
+#endif
+
/**
* hdd_napi_poll() - NAPI poll function
* @napi : pointer to NAPI struct