Explorar o código

qcacmn: Cleanup WBUFF code to support additional modules

Currently, WBUFF logic is being used only for WMI TX buffers and the
logic is closely tied to the WMI TX buffers alone. It is cumbersome
to extend the support of WBUFF for additional modules in the current
state.

Cleanup the WBUFF code and make it generic to add future module
additions.

Change-Id: Ib20ddd487b4e88c3225da1883ad9ade722c2a606
CRs-Fixed: 3520811
Manikanta Pubbisetty %!s(int64=2) %!d(string=hai) anos
pai
achega
9b27c6e104
Modificáronse 4 ficheiros con 132 adicións e 157 borrados
  1. 16 18
      wbuff/inc/wbuff.h
  2. 16 30
      wbuff/src/i_wbuff.h
  3. 74 98
      wbuff/src/wbuff.c
  4. 26 11
      wmi/src/wmi_unified.c

+ 16 - 18
wbuff/inc/wbuff.h

@@ -28,25 +28,22 @@
 #include <qdf_status.h>
 #include <qdf_nbuf.h>
 
-/* wbuff available pools */
-/* Pool of nbuf size 256 bytes */
-#define WBUFF_POOL_0 0
-/* Pool of nbuf size 512 bytes */
-#define WBUFF_POOL_1 1
-/* Pool of nbuf size 1024 bytes */
-#define WBUFF_POOL_2 2
-/* Pool of nbuf 2048 bytes */
-#define WBUFF_POOL_3 3
+enum wbuff_module_id {
+	WBUFF_MODULE_WMI_TX,
+	WBUFF_MAX_MODULES,
+};
 
 /**
  * struct wbuff_alloc_request - allocation structure for registering each
  * pool for wbuff module.
- * @slot: pool_slot identifier
- * @size: number of buffers for @pool_slot
+ * @pool_id: pool identifier
+ * @pool_size: number of buffers for @pool_id
+ * @buffer_size: size of each buffer in this @pool_id
  */
 struct wbuff_alloc_request {
-	uint8_t slot;
-	uint16_t size;
+	uint8_t pool_id;
+	uint16_t pool_size;
+	uint16_t buffer_size;
 };
 
 /* Opaque handle for wbuff */
@@ -72,16 +69,17 @@ QDF_STATUS wbuff_module_deinit(void);
 /**
  * wbuff_module_register() - Registers a module with wbuff
  * @req: allocation request from registered module
- * @num: number of pools required
+ * @num_pools: number of pools required
  * @reserve: nbuf headroom to start with
  * @align: alignment for the nbuf
+ * @module_id: module identifier
  *
  * Return: Handle if registration success
  *         NULL if registration failure
  */
 struct wbuff_mod_handle *
-wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num,
-		      int reserve, int align);
+wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num_pools,
+		      int reserve, int align, enum wbuff_module_id module_id);
 
 /**
  * wbuff_module_deregister() - De-registers a module with wbuff
@@ -127,8 +125,8 @@ static inline QDF_STATUS wbuff_module_deinit(void)
 }
 
 static inline struct wbuff_mod_handle *
-wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num,
-		      int reserve, int align)
+wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num_pools,
+		      int reserve, int align, enum wbuff_module_id module_id)
 {
 	return NULL;
 }

+ 16 - 30
wbuff/src/i_wbuff.h

@@ -27,43 +27,15 @@
 
 #include <qdf_nbuf.h>
 
-/* Number of modules supported by wbuff */
-#define WBUFF_MAX_MODULES 4
-
 /* Number of pools supported per module */
 #define WBUFF_MAX_POOLS 4
 
-/* Max buffer size supported by wbuff in bytes */
-#define WBUFF_MAX_BUFFER_SIZE 2048
-
-/* wbuff pool buffer lengths in bytes*/
-#define WBUFF_LEN_POOL0 256
-#define WBUFF_LEN_POOL1 512
-#define WBUFF_LEN_POOL2 1024
-#define WBUFF_LEN_POOL3 2048
-
-/* wbuff max pool sizes */
-/* Allocation of size 256 bytes */
-#define WBUFF_POOL_0_MAX 256
-/* Allocation of size 512 bytes */
-#define WBUFF_POOL_1_MAX 128
-/* Allocation of size 1024 bytes */
-#define WBUFF_POOL_2_MAX 64
-/* Allocation of size 2048 bytes */
-#define WBUFF_POOL_3_MAX 32
-
 #define WBUFF_MODULE_ID_SHIFT 4
 #define WBUFF_MODULE_ID_BITMASK 0xF0
 
 #define WBUFF_POOL_ID_SHIFT 1
 #define WBUFF_POOL_ID_BITMASK 0xE
 
-/* Comparison array for maximum allocation per pool*/
-uint16_t wbuff_alloc_max[WBUFF_MAX_POOLS] = {WBUFF_POOL_0_MAX,
-					     WBUFF_POOL_1_MAX,
-					     WBUFF_POOL_2_MAX,
-					     WBUFF_POOL_3_MAX};
-
 /**
  * struct wbuff_handle - wbuff handle to the registered module
  * @id: the identifier for the registered module.
@@ -72,6 +44,20 @@ struct wbuff_handle {
 	uint8_t id;
 };
 
+/**
+ * struct wbuff_pool - structure representing wbuff pool
+ * @initialized: To identify whether pool is initialized
+ * @pool: nbuf pool
+ * @buffer_size: size of the buffer in this @pool
+ * @pool_id: pool identifier
+ */
+struct wbuff_pool {
+	bool initialized;
+	qdf_nbuf_t pool;
+	uint16_t buffer_size;
+	uint8_t pool_id;
+};
+
 /**
  * struct wbuff_module - allocation holder for wbuff registered module
  * @registered: To identify whether module is registered
@@ -81,7 +67,7 @@ struct wbuff_handle {
  * @handle: wbuff handle for the registered module
  * @reserve: nbuf headroom to start with
  * @align: alignment for the nbuf
- * @pool: pools for all available buffers for the module
+ * @wbuff_pool: pools for all available buffers for the module
  */
 struct wbuff_module {
 	bool registered;
@@ -90,7 +76,7 @@ struct wbuff_module {
 	struct wbuff_handle handle;
 	int reserve;
 	int align;
-	qdf_nbuf_t pool[WBUFF_MAX_POOLS];
+	struct wbuff_pool wbuff_pool[WBUFF_MAX_POOLS];
 };
 
 /**

+ 74 - 98
wbuff/src/wbuff.c

@@ -32,72 +32,31 @@ struct wbuff_holder wbuff;
 
 /**
  * wbuff_get_pool_slot_from_len() - get pool_id from length
+ * @mod: wbuff module reference
  * @len: length of the buffer
  *
  * Return: pool_id
  */
-static uint8_t wbuff_get_pool_slot_from_len(uint16_t len)
+static uint8_t
+wbuff_get_pool_slot_from_len(struct wbuff_module *mod, uint16_t len)
 {
-	if ((len > 0) && (len <= WBUFF_LEN_POOL0))
-		return WBUFF_POOL_0;
-	else if ((len > WBUFF_LEN_POOL0) && (len <= WBUFF_LEN_POOL1))
-		return WBUFF_POOL_1;
-	else if ((len > WBUFF_LEN_POOL1) && (len <= WBUFF_LEN_POOL2))
-		return WBUFF_POOL_2;
-	else
-		return WBUFF_POOL_3;
-}
+	struct wbuff_pool *pool;
+	uint16_t prev_buf_size = 0;
+	int i;
 
-/**
- * wbuff_get_len_from_pool_slot() - get len from pool_id
- * @pool_id: pool ID
- *
- * Return: nbuf length from pool_id
- */
-static uint32_t wbuff_get_len_from_pool_slot(uint16_t pool_id)
-{
-	uint32_t len = 0;
-
-	switch (pool_id) {
-	case 0:
-		len = WBUFF_LEN_POOL0;
-		break;
-	case 1:
-		len = WBUFF_LEN_POOL1;
-		break;
-	case 2:
-		len = WBUFF_LEN_POOL2;
-		break;
-	case 3:
-		len = WBUFF_LEN_POOL3;
-		break;
-	default:
-		len = 0;
-	}
+	for (i = 0; i < WBUFF_MAX_POOLS; i++) {
+		pool = &mod->wbuff_pool[i];
 
-	return len;
-}
+		if (!pool->initialized)
+			continue;
 
-/**
- * wbuff_get_free_mod_slot() - get free module_id
- *
- * Return: module_id
- */
-static uint8_t wbuff_get_free_mod_slot(void)
-{
-	uint8_t module_id = 0;
-
-	for (module_id = 0; module_id < WBUFF_MAX_MODULES; module_id++) {
-		qdf_spin_lock_bh(&wbuff.mod[module_id].lock);
-		if (!wbuff.mod[module_id].registered) {
-			wbuff.mod[module_id].registered = true;
-			qdf_spin_unlock_bh(&wbuff.mod[module_id].lock);
+		if ((len > prev_buf_size) && (len <= pool->buffer_size))
 			break;
-		}
-		qdf_spin_unlock_bh(&wbuff.mod[module_id].lock);
+
+		prev_buf_size = mod->wbuff_pool[i].buffer_size;
 	}
 
-	return module_id;
+	return i;
 }
 
 /**
@@ -108,17 +67,13 @@ static uint8_t wbuff_get_free_mod_slot(void)
  * Return: true if valid wbuff_alloc_request
  *         false if invalid wbuff_alloc_request
  */
-static bool wbuff_is_valid_alloc_req(struct wbuff_alloc_request *req,
-				     uint8_t num)
+static bool
+wbuff_is_valid_alloc_req(struct wbuff_alloc_request *req, uint8_t num)
 {
-	uint16_t psize = 0;
-	uint8_t alloc = 0, pool_id = 0;
-
-	for (alloc = 0; alloc < num; alloc++) {
-		pool_id = req[alloc].slot;
-		psize = req[alloc].size;
-		if ((pool_id > WBUFF_MAX_POOLS - 1) ||
-		    (psize > wbuff_alloc_max[pool_id]))
+	int i;
+
+	for (i = 0; i < num; i++) {
+		if (req[i].pool_id >= WBUFF_MAX_POOLS)
 			return false;
 	}
 
@@ -142,8 +97,7 @@ static qdf_nbuf_t wbuff_prepare_nbuf(uint8_t module_id, uint8_t pool_id,
 	qdf_nbuf_t buf;
 	unsigned long dev_scratch = 0;
 
-	buf = qdf_nbuf_alloc(NULL, roundup(len + reserve, align), reserve,
-			     align, false);
+	buf = qdf_nbuf_alloc(NULL, len, reserve, align, false);
 	if (!buf)
 		return NULL;
 	dev_scratch = module_id;
@@ -184,7 +138,7 @@ QDF_STATUS wbuff_module_init(void)
 		mod = &wbuff.mod[module_id];
 		qdf_spinlock_create(&mod->lock);
 		for (pool_id = 0; pool_id < WBUFF_MAX_POOLS; pool_id++)
-			mod->pool[pool_id] = NULL;
+			mod->wbuff_pool[pool_id].pool = NULL;
 		mod->registered = false;
 	}
 	wbuff.initialized = true;
@@ -213,56 +167,69 @@ QDF_STATUS wbuff_module_deinit(void)
 }
 
 struct wbuff_mod_handle *
-wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num,
-		      int reserve, int align)
+wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num_pools,
+		      int reserve, int align, enum wbuff_module_id module_id)
 {
 	struct wbuff_module *mod = NULL;
+	struct wbuff_pool *wbuff_pool;
 	qdf_nbuf_t buf = NULL;
-	uint32_t len = 0;
-	uint16_t idx = 0, psize = 0;
-	uint8_t alloc = 0, module_id = 0, pool_id = 0;
+	uint32_t len;
+	uint16_t pool_size;
+	uint8_t pool_id;
+	int i;
+	int j;
 
 	if (!wbuff.initialized)
 		return NULL;
 
-	if ((num == 0) || (num > WBUFF_MAX_POOLS))
+	if ((num_pools == 0) || (num_pools > WBUFF_MAX_POOLS))
 		return NULL;
 
-	if (!wbuff_is_valid_alloc_req(req, num))
+	if (module_id >= WBUFF_MAX_MODULES)
 		return NULL;
 
-	module_id = wbuff_get_free_mod_slot();
-	if (module_id == WBUFF_MAX_MODULES)
+	if (!wbuff_is_valid_alloc_req(req, num_pools))
 		return NULL;
 
 	mod = &wbuff.mod[module_id];
+	if (mod->registered)
+		return NULL;
 
 	mod->handle.id = module_id;
 
-	for (alloc = 0; alloc < num; alloc++) {
-		pool_id = req[alloc].slot;
-		psize = req[alloc].size;
-		len = wbuff_get_len_from_pool_slot(pool_id);
+	for (i = 0; i < num_pools; i++) {
+		pool_id = req[i].pool_id;
+		pool_size = req[i].pool_size;
+		len = req[i].buffer_size;
+		wbuff_pool = &mod->wbuff_pool[pool_id];
+
 		/**
-		 * Allocate pool_cnt number of buffers for
+		 * Allocate pool_size number of buffers for
 		 * the pool given by pool_id
 		 */
-		for (idx = 0; idx < psize; idx++) {
+		for (j = 0; j < pool_size; j++) {
 			buf = wbuff_prepare_nbuf(module_id, pool_id, len,
 						 reserve, align);
 			if (!buf)
 				continue;
-			if (!mod->pool[pool_id]) {
+
+			if (!wbuff_pool->pool)
 				qdf_nbuf_set_next(buf, NULL);
-				mod->pool[pool_id] = buf;
-			} else {
-				qdf_nbuf_set_next(buf, mod->pool[pool_id]);
-				mod->pool[pool_id] = buf;
-			}
+			else
+				qdf_nbuf_set_next(buf, wbuff_pool->pool);
+
+			wbuff_pool->pool = buf;
 		}
+
+		wbuff_pool->pool_id = pool_id;
+		wbuff_pool->buffer_size = len;
+		wbuff_pool->initialized = true;
 	}
+
 	mod->reserve = reserve;
 	mod->align = align;
+	mod->registered = true;
+
 
 	return (struct wbuff_mod_handle *)&mod->handle;
 }
@@ -284,7 +251,7 @@ QDF_STATUS wbuff_module_deregister(struct wbuff_mod_handle *hdl)
 
 	qdf_spin_lock_bh(&mod->lock);
 	for (pool_id = 0; pool_id < WBUFF_MAX_POOLS; pool_id++) {
-		first = mod->pool[pool_id];
+		first = mod->wbuff_pool[pool_id].pool;
 		while (first) {
 			buf = first;
 			first = qdf_nbuf_next(buf);
@@ -302,27 +269,33 @@ qdf_nbuf_t wbuff_buff_get(struct wbuff_mod_handle *hdl, uint32_t len,
 {
 	struct wbuff_handle *handle;
 	struct wbuff_module *mod = NULL;
+	struct wbuff_pool *wbuff_pool;
 	uint8_t module_id = 0;
 	uint8_t pool_id = 0;
 	qdf_nbuf_t buf = NULL;
 
 	handle = (struct wbuff_handle *)hdl;
 
-	if ((!wbuff.initialized) || (!wbuff_is_valid_handle(handle)) || !len ||
-	    (len > WBUFF_MAX_BUFFER_SIZE))
+	if ((!wbuff.initialized) || (!wbuff_is_valid_handle(handle)) || !len)
 		return NULL;
 
 	module_id = handle->id;
-	pool_id = wbuff_get_pool_slot_from_len(len);
 	mod = &wbuff.mod[module_id];
 
+	pool_id = wbuff_get_pool_slot_from_len(mod, len);
+	if (pool_id == WBUFF_MAX_POOLS)
+		return NULL;
+
+	wbuff_pool = &mod->wbuff_pool[pool_id];
+
 	qdf_spin_lock_bh(&mod->lock);
-	if (mod->pool[pool_id]) {
-		buf = mod->pool[pool_id];
-		mod->pool[pool_id] = qdf_nbuf_next(buf);
+	if (wbuff_pool->pool) {
+		buf = wbuff_pool->pool;
+		wbuff_pool->pool = qdf_nbuf_next(buf);
 		mod->pending_returns++;
 	}
 	qdf_spin_unlock_bh(&mod->lock);
+
 	if (buf) {
 		qdf_nbuf_set_next(buf, NULL);
 		qdf_net_buf_debug_update_node(buf, func_name, line_num);
@@ -336,6 +309,7 @@ qdf_nbuf_t wbuff_buff_put(qdf_nbuf_t buf)
 	qdf_nbuf_t buffer = buf;
 	unsigned long pool_info = 0;
 	uint8_t module_id = 0, pool_id = 0;
+	struct wbuff_pool *wbuff_pool;
 
 	if (!wbuff.initialized)
 		return buffer;
@@ -351,13 +325,15 @@ qdf_nbuf_t wbuff_buff_put(qdf_nbuf_t buf)
 	if (module_id >= WBUFF_MAX_MODULES || pool_id >= WBUFF_MAX_POOLS)
 		return NULL;
 
+	wbuff_pool = &wbuff.mod[module_id].wbuff_pool[pool_id];
+
 	qdf_nbuf_reset(buffer, wbuff.mod[module_id].reserve,
 		       wbuff.mod[module_id].align);
 
 	qdf_spin_lock_bh(&wbuff.mod[module_id].lock);
 	if (wbuff.mod[module_id].registered) {
-		qdf_nbuf_set_next(buffer, wbuff.mod[module_id].pool[pool_id]);
-		wbuff.mod[module_id].pool[pool_id] = buffer;
+		qdf_nbuf_set_next(buffer, wbuff_pool->pool);
+		wbuff_pool->pool = buffer;
 		wbuff.mod[module_id].pending_returns--;
 		buffer = NULL;
 	}

+ 26 - 11
wmi/src/wmi_unified.c

@@ -112,6 +112,12 @@ typedef PREPACK struct {
 /* Allocation of size 2048 bytes */
 #define WMI_WBUFF_POOL_3_SIZE 8
 
+/* wbuff pool buffer lengths in bytes for WMI*/
+#define WMI_WBUFF_LEN_POOL0 256
+#define WMI_WBUFF_LEN_POOL1 512
+#define WMI_WBUFF_LEN_POOL2 1024
+#define WMI_WBUFF_LEN_POOL3 2048
+
 #define RX_DIAG_EVENT_WORK_PROCESS_MAX_COUNT 500
 
 #ifdef WMI_INTERFACE_EVENT_LOGGING
@@ -3269,18 +3275,27 @@ qdf_export_symbol(wmi_unified_register_module);
 static void wmi_wbuff_register(struct wmi_unified *wmi_handle)
 {
 	struct wbuff_alloc_request wbuff_alloc[4];
+	uint8_t reserve = WMI_MIN_HEAD_ROOM;
+
+	wbuff_alloc[0].pool_id = 0;
+	wbuff_alloc[0].pool_size = WMI_WBUFF_POOL_0_SIZE;
+	wbuff_alloc[0].buffer_size = roundup(WMI_WBUFF_LEN_POOL0 + reserve, 4);
+
+	wbuff_alloc[1].pool_id = 1;
+	wbuff_alloc[1].pool_size = WMI_WBUFF_POOL_1_SIZE;
+	wbuff_alloc[1].buffer_size = roundup(WMI_WBUFF_LEN_POOL1 + reserve, 4);
+
+	wbuff_alloc[2].pool_id = 2;
+	wbuff_alloc[2].pool_size = WMI_WBUFF_POOL_2_SIZE;
+	wbuff_alloc[2].buffer_size = roundup(WMI_WBUFF_LEN_POOL2 + reserve, 4);
+
+	wbuff_alloc[3].pool_id = 3;
+	wbuff_alloc[3].pool_size = WMI_WBUFF_POOL_3_SIZE;
+	wbuff_alloc[3].buffer_size = roundup(WMI_WBUFF_LEN_POOL3 + reserve, 4);
 
-	wbuff_alloc[0].slot = WBUFF_POOL_0;
-	wbuff_alloc[0].size = WMI_WBUFF_POOL_0_SIZE;
-	wbuff_alloc[1].slot = WBUFF_POOL_1;
-	wbuff_alloc[1].size = WMI_WBUFF_POOL_1_SIZE;
-	wbuff_alloc[2].slot = WBUFF_POOL_2;
-	wbuff_alloc[2].size = WMI_WBUFF_POOL_2_SIZE;
-	wbuff_alloc[3].slot = WBUFF_POOL_3;
-	wbuff_alloc[3].size = WMI_WBUFF_POOL_3_SIZE;
-
-	wmi_handle->wbuff_handle = wbuff_module_register(wbuff_alloc, 4,
-							 WMI_MIN_HEAD_ROOM, 4);
+	wmi_handle->wbuff_handle =
+		wbuff_module_register(wbuff_alloc, QDF_ARRAY_SIZE(wbuff_alloc),
+				      reserve, 4, WBUFF_MODULE_WMI_TX);
 }
 
 /**