forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/hnd_pktpool.c
....@@ -1,15 +1,16 @@
1
-/* SPDX-License-Identifier: GPL-2.0 */
21 /*
32 * HND generic packet pool operation primitives
43 *
5
- * Copyright (C) 1999-2019, Broadcom Corporation
6
- *
4
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
5
+ *
6
+ * Copyright (C) 1999-2017, Broadcom Corporation
7
+ *
78 * Unless you and Broadcom execute a separate written software license
89 * agreement governing use of this software, this software is licensed to you
910 * under the terms of the GNU General Public License version 2 (the "GPL"),
1011 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
1112 * following added to such license:
12
- *
13
+ *
1314 * As a special exception, the copyright holders of this software give you
1415 * permission to link this software with independent modules, and to copy and
1516 * distribute the resulting executable under terms of your choice, provided that
....@@ -17,7 +18,7 @@
1718 * the license of that module. An independent module is a module which is not
1819 * derived from this software. The special exception does not apply to any
1920 * modifications of the software.
20
- *
21
+ *
2122 * Notwithstanding the above, under no circumstances may you combine this
2223 * software in any way with any other Broadcom software provided under a license
2324 * other than the GPL, without Broadcom's express prior written consent.
....@@ -25,7 +26,7 @@
2526 *
2627 * <<Broadcom-WL-IPTag/Open:>>
2728 *
28
- * $Id: $
29
+ * $Id: hnd_pktpool.c 677681 2017-01-04 09:10:30Z $
2930 */
3031
3132 #include <typedefs.h>
....@@ -33,6 +34,12 @@
3334 #include <osl_ext.h>
3435 #include <bcmutils.h>
3536 #include <hnd_pktpool.h>
37
+#ifdef BCMRESVFRAGPOOL
38
+#include <hnd_resvpool.h>
39
+#endif /* BCMRESVFRAGPOOL */
40
+#ifdef BCMFRWDPOOLREORG
41
+#include <hnd_poolreorg.h>
42
+#endif /* BCMFRWDPOOLREORG */
3643
3744 /* mutex macros for thread safe */
3845 #ifdef HND_PKTPOOL_THREAD_SAFE
....@@ -45,7 +52,7 @@
4552 #define HND_PKTPOOL_MUTEX_DELETE(mutex) OSL_EXT_SUCCESS
4653 #define HND_PKTPOOL_MUTEX_ACQUIRE(mutex, msec) OSL_EXT_SUCCESS
4754 #define HND_PKTPOOL_MUTEX_RELEASE(mutex) OSL_EXT_SUCCESS
48
-#endif
55
+#endif // endif
4956
5057 /* Registry size is one larger than max pools, as slot #0 is reserved */
5158 #define PKTPOOLREG_RSVD_ID (0U)
....@@ -85,10 +92,9 @@
8592 static int pktpool_deregister(pktpool_t * poolptr);
8693
8794 /** add declaration */
88
-static int pktpool_avail_notify(pktpool_t *pktp);
95
+static void pktpool_avail_notify(pktpool_t *pktp);
8996
9097 /** accessor functions required when ROMming this file, forced into RAM */
91
-
9298
9399 pktpool_t *
94100 BCMRAMFN(get_pktpools_registry)(int id)
....@@ -108,10 +114,12 @@
108114 return pktpools_registry[id] == pp;
109115 }
110116
111
-int /* Construct a pool registry to serve a maximum of total_pools */
117
+/** Constructs a pool registry to serve a maximum of total_pools */
118
+int
112119 pktpool_attach(osl_t *osh, uint32 total_pools)
113120 {
114121 uint32 poolid;
122
+ BCM_REFERENCE(osh);
115123
116124 if (pktpools_max != 0U) {
117125 return BCME_ERROR;
....@@ -131,10 +139,12 @@
131139 return (int)pktpools_max;
132140 }
133141
134
-int /* Destruct the pool registry. Ascertain all pools were first de-inited */
142
+/** Destructs the pool registry. Ascertain all pools were first de-inited */
143
+int
135144 pktpool_dettach(osl_t *osh)
136145 {
137146 uint32 poolid;
147
+ BCM_REFERENCE(osh);
138148
139149 if (pktpools_max == 0U) {
140150 return BCME_OK;
....@@ -152,7 +162,8 @@
152162 return BCME_OK;
153163 }
154164
155
-static int /* Register a pool in a free slot; return the registry slot index */
165
+/** Registers a pool in a free slot; returns the registry slot index */
166
+static int
156167 pktpool_register(pktpool_t * poolptr)
157168 {
158169 uint32 poolid;
....@@ -174,7 +185,8 @@
174185 return PKTPOOL_INVALID_ID; /* error: registry is full */
175186 }
176187
177
-static int /* Deregister a pktpool, given the pool pointer; tag slot as free */
188
+/** Deregisters a pktpool, given the pool pointer; tag slot as free */
189
+static int
178190 pktpool_deregister(pktpool_t * poolptr)
179191 {
180192 uint32 poolid;
....@@ -195,12 +207,10 @@
195207 return BCME_OK;
196208 }
197209
198
-
199
-/*
210
+/**
200211 * pktpool_init:
201
- * User provides a pktpool_t sturcture and specifies the number of packets to
202
- * be pre-filled into the pool (pplen). The size of all packets in a pool must
203
- * be the same and is specified by plen.
212
+ * User provides a pktpool_t structure and specifies the number of packets to
213
+ * be pre-filled into the pool (n_pkts).
204214 * pktpool_init first attempts to register the pool and fetch a unique poolid.
205215 * If registration fails, it is considered an BCME_ERR, caused by either the
206216 * registry was not pre-created (pktpool_attach) or the registry is full.
....@@ -211,9 +221,14 @@
211221 * In dongle builds, prior to memory reclaimation, one should limit the number
212222 * of packets to be allocated during pktpool_init and fill the pool up after
213223 * reclaim stage.
224
+ *
225
+ * @param n_pkts Number of packets to be pre-filled into the pool
226
+ * @param max_pkt_bytes The size of all packets in a pool must be the same. E.g. PKTBUFSZ.
227
+ * @param type e.g. 'lbuf_frag'
214228 */
215229 int
216
-pktpool_init(osl_t *osh, pktpool_t *pktp, int *pplen, int plen, bool istx, uint8 type)
230
+pktpool_init(osl_t *osh, pktpool_t *pktp, int *n_pkts, int max_pkt_bytes, bool istx,
231
+ uint8 type)
217232 {
218233 int i, err = BCME_OK;
219234 int pktplen;
....@@ -221,9 +236,9 @@
221236
222237 ASSERT(pktp != NULL);
223238 ASSERT(osh != NULL);
224
- ASSERT(pplen != NULL);
239
+ ASSERT(n_pkts != NULL);
225240
226
- pktplen = *pplen;
241
+ pktplen = *n_pkts;
227242
228243 bzero(pktp, sizeof(pktpool_t));
229244
....@@ -235,7 +250,7 @@
235250
236251 pktp->inited = TRUE;
237252 pktp->istx = istx ? TRUE : FALSE;
238
- pktp->plen = (uint16)plen;
253
+ pktp->max_pkt_bytes = (uint16)max_pkt_bytes;
239254 pktp->type = type;
240255
241256 if (HND_PKTPOOL_MUTEX_CREATE("pktpool", &pktp->mutex) != OSL_EXT_SUCCESS) {
....@@ -247,7 +262,7 @@
247262
248263 for (i = 0; i < pktplen; i++) {
249264 void *p;
250
- p = PKTGET(osh, plen, TRUE);
265
+ p = PKTGET(osh, max_pkt_bytes, TRUE);
251266
252267 if (p == NULL) {
253268 /* Not able to allocate all requested pkts
....@@ -269,17 +284,17 @@
269284
270285 #ifdef BCMDBG_POOL
271286 pktp->dbg_q[pktp->dbg_qlen++].p = p;
272
-#endif
287
+#endif // endif
273288 }
274289
275290 exit:
276
- pktp->len = pktp->avail;
291
+ pktp->n_pkts = pktp->avail;
277292
278
- *pplen = pktp->len;
293
+ *n_pkts = pktp->n_pkts; /* number of packets managed by pool */
279294 return err;
280
-}
295
+} /* pktpool_init */
281296
282
-/*
297
+/**
283298 * pktpool_deinit:
284299 * Prior to freeing a pktpool, all packets must be first freed into the pktpool.
285300 * Upon pktpool_deinit, all packets in the free pool will be freed to the heap.
....@@ -298,11 +313,11 @@
298313 #ifdef BCMDBG_POOL
299314 {
300315 int i;
301
- for (i = 0; i <= pktp->len; i++) {
316
+ for (i = 0; i <= pktp->n_pkts; i++) {
302317 pktp->dbg_q[i].p = NULL;
303318 }
304319 }
305
-#endif
320
+#endif // endif
306321
307322 while (pktp->freelist != NULL) {
308323 void * p = pktp->freelist;
....@@ -315,13 +330,13 @@
315330 PKTFREE(osh, p, pktp->istx); /* free the packet */
316331
317332 freed++;
318
- ASSERT(freed <= pktp->len);
333
+ ASSERT(freed <= pktp->n_pkts);
319334 }
320335
321336 pktp->avail -= freed;
322337 ASSERT(pktp->avail == 0);
323338
324
- pktp->len -= freed;
339
+ pktp->n_pkts -= freed;
325340
326341 pktpool_deregister(pktp); /* release previously acquired unique pool id */
327342 POOLSETID(pktp, PKTPOOL_INVALID_ID);
....@@ -332,7 +347,7 @@
332347 pktp->inited = FALSE;
333348
334349 /* Are there still pending pkts? */
335
- ASSERT(pktp->len == 0);
350
+ ASSERT(pktp->n_pkts == 0);
336351
337352 return 0;
338353 }
....@@ -342,19 +357,19 @@
342357 {
343358 void *p;
344359 int err = 0;
345
- int len, psize, maxlen;
360
+ int n_pkts, psize, maxlen;
346361
347362 /* protect shared resource */
348363 if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
349364 return BCME_ERROR;
350365
351
- ASSERT(pktp->plen != 0);
366
+ ASSERT(pktp->max_pkt_bytes != 0);
352367
353368 maxlen = pktp->maxlen;
354369 psize = minimal ? (maxlen >> 2) : maxlen;
355
- for (len = (int)pktp->len; len < psize; len++) {
370
+ for (n_pkts = (int)pktp->n_pkts; n_pkts < psize; n_pkts++) {
356371
357
- p = PKTGET(osh, pktp->len, TRUE);
372
+ p = PKTGET(osh, pktp->n_pkts, TRUE);
358373
359374 if (p == NULL) {
360375 err = BCME_NOMEM;
....@@ -380,6 +395,134 @@
380395 return err;
381396 }
382397
398
+#ifdef BCMPOOLRECLAIM
399
+/* New API to decrease the pkts from pool, but not deinit
400
+*/
401
+uint16
402
+pktpool_reclaim(osl_t *osh, pktpool_t *pktp, uint16 free_cnt)
403
+{
404
+ uint16 freed = 0;
405
+
406
+ pktpool_cb_extn_t cb = NULL;
407
+ void *arg = NULL;
408
+
409
+ ASSERT(osh != NULL);
410
+ ASSERT(pktp != NULL);
411
+
412
+ /* protect shared resource */
413
+ if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS) {
414
+ return freed;
415
+ }
416
+
417
+ if (pktp->avail < free_cnt) {
418
+ free_cnt = pktp->avail;
419
+ }
420
+
421
+ if (BCMSPLITRX_ENAB() && (pktp->type == lbuf_rxfrag)) {
422
+ /* If pool is shared rx frag pool, use call back fn to reclaim host address
423
+ * and Rx cpl ID associated with the pkt.
424
+ */
425
+ ASSERT(pktp->cbext.cb != NULL);
426
+
427
+ cb = pktp->cbext.cb;
428
+ arg = pktp->cbext.arg;
429
+
430
+ } else if ((pktp->type == lbuf_basic) && (pktp->rxcplidfn.cb != NULL)) {
431
+ /* If pool is shared rx pool, use call back fn to freeup Rx cpl ID
432
+ * associated with the pkt.
433
+ */
434
+ cb = pktp->rxcplidfn.cb;
435
+ arg = pktp->rxcplidfn.arg;
436
+ }
437
+
438
+ while ((pktp->freelist != NULL) && (free_cnt)) {
439
+ void * p = pktp->freelist;
440
+
441
+ pktp->freelist = PKTFREELIST(p); /* unlink head packet from free list */
442
+ PKTSETFREELIST(p, NULL);
443
+
444
+ if (cb != NULL) {
445
+ if (cb(pktp, arg, p, REMOVE_RXCPLID)) {
446
+ PKTSETFREELIST(p, pktp->freelist);
447
+ pktp->freelist = p;
448
+ break;
449
+ }
450
+ }
451
+
452
+ PKTSETPOOL(osh, p, FALSE, NULL); /* clear pool ID tag in pkt */
453
+
454
+ PKTFREE(osh, p, pktp->istx); /* free the packet */
455
+
456
+ freed++;
457
+ free_cnt--;
458
+ }
459
+
460
+ pktp->avail -= freed;
461
+
462
+ pktp->n_pkts -= freed;
463
+
464
+ /* protect shared resource */
465
+ if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS) {
466
+ return freed;
467
+ }
468
+
469
+ return freed;
470
+}
471
+#endif /* #ifdef BCMPOOLRECLAIM */
472
+
473
+/* New API to empty the pkts from pool, but not deinit
474
+* NOTE: caller is responsible to ensure,
475
+* all pkts are available in pool for free; else LEAK !
476
+*/
477
+int
478
+pktpool_empty(osl_t *osh, pktpool_t *pktp)
479
+{
480
+ uint16 freed = 0;
481
+
482
+ ASSERT(osh != NULL);
483
+ ASSERT(pktp != NULL);
484
+
485
+ /* protect shared resource */
486
+ if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
487
+ return BCME_ERROR;
488
+
489
+#ifdef BCMDBG_POOL
490
+ {
491
+ int i;
492
+ for (i = 0; i <= pktp->n_pkts; i++) {
493
+ pktp->dbg_q[i].p = NULL;
494
+ }
495
+ }
496
+#endif // endif
497
+
498
+ while (pktp->freelist != NULL) {
499
+ void * p = pktp->freelist;
500
+
501
+ pktp->freelist = PKTFREELIST(p); /* unlink head packet from free list */
502
+ PKTSETFREELIST(p, NULL);
503
+
504
+ PKTSETPOOL(osh, p, FALSE, NULL); /* clear pool ID tag in pkt */
505
+
506
+ PKTFREE(osh, p, pktp->istx); /* free the packet */
507
+
508
+ freed++;
509
+ ASSERT(freed <= pktp->n_pkts);
510
+ }
511
+
512
+ pktp->avail -= freed;
513
+ ASSERT(pktp->avail == 0);
514
+
515
+ pktp->n_pkts -= freed;
516
+
517
+ ASSERT(pktp->n_pkts == 0);
518
+
519
+ /* protect shared resource */
520
+ if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
521
+ return BCME_ERROR;
522
+
523
+ return 0;
524
+}
525
+
383526 static void *
384527 pktpool_deq(pktpool_t *pktp)
385528 {
....@@ -392,6 +535,7 @@
392535
393536 p = pktp->freelist; /* dequeue packet from head of pktpool free list */
394537 pktp->freelist = PKTFREELIST(p); /* free list points to next packet */
538
+
395539 PKTSETFREELIST(p, NULL);
396540
397541 pktp->avail--;
....@@ -408,10 +552,10 @@
408552 pktp->freelist = p; /* free list points to newly inserted packet */
409553
410554 pktp->avail++;
411
- ASSERT(pktp->avail <= pktp->len);
555
+ ASSERT(pktp->avail <= pktp->n_pkts);
412556 }
413557
414
-/* utility for registering host addr fill function called from pciedev */
558
+/** utility for registering host addr fill function called from pciedev */
415559 int
416560 /* BCMATTACHFN */
417561 (pktpool_hostaddr_fill_register)(pktpool_t *pktp, pktpool_cb_extn_t cb, void *arg)
....@@ -438,8 +582,8 @@
438582 pktp->rxcplidfn.arg = arg;
439583 return 0;
440584 }
441
-/* Callback functions for split rx modes */
442
-/* when evr host posts rxbuffer, invike dma_rxfill from pciedev layer */
585
+
586
+/** whenever host posts rxbuffer, invoke dma_rxfill from pciedev layer */
443587 void
444588 pktpool_invoke_dmarxfill(pktpool_t *pktp)
445589 {
....@@ -449,6 +593,8 @@
449593 if (pktp->dmarxfill.cb)
450594 pktp->dmarxfill.cb(pktp, pktp->dmarxfill.arg);
451595 }
596
+
597
+/** Registers callback functions for split rx mode */
452598 int
453599 pkpool_haddr_avail_register_cb(pktpool_t *pktp, pktpool_cb_t cb, void *arg)
454600 {
....@@ -460,7 +606,11 @@
460606
461607 return 0;
462608 }
463
-/* No BCMATTACHFN as it is used in xdc_enable_ep which is not an attach function */
609
+
610
+/**
611
+ * Registers callback functions.
612
+ * No BCMATTACHFN as it is used in xdc_enable_ep which is not an attach function
613
+ */
464614 int
465615 pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg)
466616 {
....@@ -473,6 +623,14 @@
473623
474624 ASSERT(cb != NULL);
475625
626
+ for (i = 0; i < pktp->cbcnt; i++) {
627
+ ASSERT(pktp->cbs[i].cb != NULL);
628
+ if ((cb == pktp->cbs[i].cb) && (arg == pktp->cbs[i].arg)) {
629
+ pktp->cbs[i].refcnt++;
630
+ goto done;
631
+ }
632
+ }
633
+
476634 i = pktp->cbcnt;
477635 if (i == PKTPOOL_CB_MAX_AVL) {
478636 err = BCME_ERROR;
....@@ -482,6 +640,7 @@
482640 ASSERT(pktp->cbs[i].cb == NULL);
483641 pktp->cbs[i].cb = cb;
484642 pktp->cbs[i].arg = arg;
643
+ pktp->cbs[i].refcnt++;
485644 pktp->cbcnt++;
486645
487646 done:
....@@ -492,6 +651,55 @@
492651 return err;
493652 }
494653
654
+/* No BCMATTACHFN as it is used in a non-attach function */
655
+int
656
+pktpool_avail_deregister(pktpool_t *pktp, pktpool_cb_t cb, void *arg)
657
+{
658
+ int err = 0;
659
+ int i, k;
660
+
661
+ /* protect shared resource */
662
+ if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS) {
663
+ return BCME_ERROR;
664
+ }
665
+
666
+ ASSERT(cb != NULL);
667
+
668
+ for (i = 0; i < pktp->cbcnt; i++) {
669
+ ASSERT(pktp->cbs[i].cb != NULL);
670
+ if ((cb == pktp->cbs[i].cb) && (arg == pktp->cbs[i].arg)) {
671
+ pktp->cbs[i].refcnt--;
672
+ if (pktp->cbs[i].refcnt) {
673
+ /* Still there are references to this callback */
674
+ goto done;
675
+ }
676
+ /* Moving any more callbacks to fill the hole */
677
+ for (k = i+1; k < pktp->cbcnt; i++, k++) {
678
+ pktp->cbs[i].cb = pktp->cbs[k].cb;
679
+ pktp->cbs[i].arg = pktp->cbs[k].arg;
680
+ pktp->cbs[i].refcnt = pktp->cbs[k].refcnt;
681
+ }
682
+
683
+ /* reset the last callback */
684
+ pktp->cbs[i].cb = NULL;
685
+ pktp->cbs[i].arg = NULL;
686
+ pktp->cbs[i].refcnt = 0;
687
+
688
+ pktp->cbcnt--;
689
+ goto done;
690
+ }
691
+ }
692
+
693
+done:
694
+ /* protect shared resource */
695
+ if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS) {
696
+ return BCME_ERROR;
697
+ }
698
+
699
+ return err;
700
+}
701
+
702
+/** Registers callback functions */
495703 int
496704 pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg)
497705 {
....@@ -523,6 +731,7 @@
523731 return err;
524732 }
525733
734
+/** Calls registered callback functions */
526735 static int
527736 pktpool_empty_notify(pktpool_t *pktp)
528737 {
....@@ -688,6 +897,7 @@
688897 }
689898
690899 int pktpool_stop_trigger(pktpool_t *pktp, void *p);
900
+
691901 int
692902 pktpool_stop_trigger(pktpool_t *pktp, void *p)
693903 {
....@@ -732,6 +942,7 @@
732942 int
733943 pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp)
734944 {
945
+ BCM_REFERENCE(osh);
735946 ASSERT(pktp);
736947
737948 /* protect shared resource */
....@@ -752,6 +963,7 @@
752963 {
753964 int i;
754965 int err;
966
+ BCM_REFERENCE(osh);
755967
756968 ASSERT(pktp);
757969
....@@ -779,7 +991,7 @@
779991 return err;
780992 }
781993
782
-static int
994
+static void
783995 pktpool_avail_notify(pktpool_t *pktp)
784996 {
785997 int i, k, idx;
....@@ -788,7 +1000,7 @@
7881000 ASSERT(pktp);
7891001 if (pktp->availcb_excl != NULL) {
7901002 pktp->availcb_excl->cb(pktp, pktp->availcb_excl->arg);
791
- return 0;
1003
+ return;
7921004 }
7931005
7941006 k = pktp->cbcnt - 1;
....@@ -810,9 +1022,10 @@
8101022 */
8111023 pktp->cbtoggle ^= 1;
8121024
813
- return 0;
1025
+ return;
8141026 }
8151027
1028
+/** Gets an empty packet from the caller provided pool */
8161029 void *
8171030 pktpool_get(pktpool_t *pktp)
8181031 {
....@@ -821,7 +1034,6 @@
8211034 /* protect shared resource */
8221035 if (HND_PKTPOOL_MUTEX_ACQUIRE(&pktp->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS)
8231036 return NULL;
824
-
8251037
8261038 p = pktpool_deq(pktp);
8271039
....@@ -834,7 +1046,6 @@
8341046 if (p == NULL)
8351047 goto done;
8361048 }
837
-
8381049
8391050 done:
8401051 /* protect shared resource */
....@@ -854,7 +1065,7 @@
8541065 ASSERT(p != NULL);
8551066 #ifdef BCMDBG_POOL
8561067 /* pktpool_stop_trigger(pktp, p); */
857
-#endif
1068
+#endif // endif
8581069
8591070 pktpool_enq(pktp, p);
8601071
....@@ -888,6 +1099,7 @@
8881099 return;
8891100 }
8901101
1102
+/** Adds a caller provided (empty) packet to the caller provided pool */
8911103 int
8921104 pktpool_add(pktpool_t *pktp, void *p)
8931105 {
....@@ -899,21 +1111,21 @@
8991111
9001112 ASSERT(p != NULL);
9011113
902
- if (pktp->len == pktp->maxlen) {
1114
+ if (pktp->n_pkts == pktp->maxlen) {
9031115 err = BCME_RANGE;
9041116 goto done;
9051117 }
9061118
9071119 /* pkts in pool have same length */
908
- ASSERT(pktp->plen == PKTLEN(OSH_NULL, p));
1120
+ ASSERT(pktp->max_pkt_bytes == PKTLEN(OSH_NULL, p));
9091121 PKTSETPOOL(OSH_NULL, p, TRUE, pktp);
9101122
911
- pktp->len++;
1123
+ pktp->n_pkts++;
9121124 pktpool_enq(pktp, p);
9131125
9141126 #ifdef BCMDBG_POOL
9151127 pktp->dbg_q[pktp->dbg_qlen++].p = p;
916
-#endif
1128
+#endif // endif
9171129
9181130 done:
9191131 /* protect shared resource */
....@@ -923,7 +1135,8 @@
9231135 return err;
9241136 }
9251137
926
-/* Force pktpool_setmaxlen () into RAM as it uses a constant
1138
+/**
1139
+ * Force pktpool_setmaxlen () into RAM as it uses a constant
9271140 * (PKTPOOL_LEN_MAX) that may be changed post tapeout for ROM-based chips.
9281141 */
9291142 int
....@@ -940,7 +1153,7 @@
9401153 * since we currently do not reduce the pool len
9411154 * already allocated
9421155 */
943
- pktp->maxlen = (pktp->len > maxlen) ? pktp->len : maxlen;
1156
+ pktp->maxlen = (pktp->n_pkts > maxlen) ? pktp->n_pkts : maxlen;
9441157
9451158 /* protect shared resource */
9461159 if (HND_PKTPOOL_MUTEX_RELEASE(&pktp->mutex) != OSL_EXT_SUCCESS)
....@@ -984,27 +1197,37 @@
9841197
9851198 #ifdef BCMFRAGPOOL
9861199 pktpool_t *pktpool_shared_lfrag = NULL;
1200
+#ifdef BCMRESVFRAGPOOL
1201
+pktpool_t *pktpool_resv_lfrag = NULL;
1202
+struct resv_info *resv_pool_info = NULL;
1203
+#endif /* BCMRESVFRAGPOOL */
9871204 #endif /* BCMFRAGPOOL */
9881205
9891206 pktpool_t *pktpool_shared_rxlfrag = NULL;
9901207
9911208 static osl_t *pktpool_osh = NULL;
9921209
993
-void
1210
+/**
1211
+ * Initializes several packet pools and allocates packets within those pools.
1212
+ */
1213
+int
9941214 hnd_pktpool_init(osl_t *osh)
9951215 {
1216
+ int err = BCME_OK;
9961217 int n;
9971218
9981219 /* Construct a packet pool registry before initializing packet pools */
9991220 n = pktpool_attach(osh, PKTPOOL_MAXIMUM_ID);
10001221 if (n != PKTPOOL_MAXIMUM_ID) {
10011222 ASSERT(0);
1002
- return;
1223
+ err = BCME_ERROR;
1224
+ goto error0;
10031225 }
10041226
10051227 pktpool_shared = MALLOCZ(osh, sizeof(pktpool_t));
10061228 if (pktpool_shared == NULL) {
10071229 ASSERT(0);
1230
+ err = BCME_NOMEM;
10081231 goto error1;
10091232 }
10101233
....@@ -1012,18 +1235,31 @@
10121235 pktpool_shared_lfrag = MALLOCZ(osh, sizeof(pktpool_t));
10131236 if (pktpool_shared_lfrag == NULL) {
10141237 ASSERT(0);
1238
+ err = BCME_NOMEM;
10151239 goto error2;
10161240 }
1017
-#endif
1241
+#if defined(BCMRESVFRAGPOOL) && !defined(BCMRESVFRAGPOOL_DISABLED)
1242
+ resv_pool_info = hnd_resv_pool_alloc(osh);
1243
+ if (resv_pool_info == NULL) {
1244
+ ASSERT(0);
1245
+ goto error2;
1246
+ }
1247
+ pktpool_resv_lfrag = resv_pool_info->pktp;
1248
+ if (pktpool_resv_lfrag == NULL) {
1249
+ ASSERT(0);
1250
+ goto error2;
1251
+ }
1252
+#endif /* RESVFRAGPOOL */
1253
+#endif /* FRAGPOOL */
10181254
10191255 #if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
10201256 pktpool_shared_rxlfrag = MALLOCZ(osh, sizeof(pktpool_t));
10211257 if (pktpool_shared_rxlfrag == NULL) {
10221258 ASSERT(0);
1259
+ err = BCME_NOMEM;
10231260 goto error3;
10241261 }
1025
-#endif
1026
-
1262
+#endif // endif
10271263
10281264 /*
10291265 * At this early stage, there's not enough memory to allocate all
....@@ -1039,8 +1275,9 @@
10391275 * were not filled into the pool.
10401276 */
10411277 n = 1;
1042
- if (pktpool_init(osh, pktpool_shared,
1043
- &n, PKTBUFSZ, FALSE, lbuf_basic) == BCME_ERROR) {
1278
+ MALLOC_SET_NOPERSIST(osh); /* Ensure subsequent allocations are non-persist */
1279
+ if ((err = pktpool_init(osh, pktpool_shared,
1280
+ &n, PKTBUFSZ, FALSE, lbuf_basic)) != BCME_OK) {
10441281 ASSERT(0);
10451282 goto error4;
10461283 }
....@@ -1048,40 +1285,76 @@
10481285
10491286 #if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
10501287 n = 1;
1051
- if (pktpool_init(osh, pktpool_shared_lfrag,
1052
- &n, PKTFRAGSZ, TRUE, lbuf_frag) == BCME_ERROR) {
1288
+ if ((err = pktpool_init(osh, pktpool_shared_lfrag,
1289
+ &n, PKTFRAGSZ, TRUE, lbuf_frag)) != BCME_OK) {
10531290 ASSERT(0);
10541291 goto error5;
10551292 }
10561293 pktpool_setmaxlen(pktpool_shared_lfrag, SHARED_FRAG_POOL_LEN);
1057
-#endif
1294
+#if defined(BCMRESVFRAGPOOL) && !defined(BCMRESVFRAGPOOL_DISABLED)
1295
+ n = 0; /* IMPORTANT: DO NOT allocate any packets in resv pool */
1296
+ if (pktpool_init(osh, pktpool_resv_lfrag,
1297
+ &n, PKTFRAGSZ, TRUE, lbuf_frag) == BCME_ERROR) {
1298
+ ASSERT(0);
1299
+ goto error5;
1300
+ }
1301
+ pktpool_setmaxlen(pktpool_resv_lfrag, RESV_FRAG_POOL_LEN);
1302
+#endif /* RESVFRAGPOOL */
1303
+#endif /* BCMFRAGPOOL */
10581304 #if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
10591305 n = 1;
1060
- if (pktpool_init(osh, pktpool_shared_rxlfrag,
1061
- &n, PKTRXFRAGSZ, TRUE, lbuf_rxfrag) == BCME_ERROR) {
1306
+ if ((err = pktpool_init(osh, pktpool_shared_rxlfrag,
1307
+ &n, PKTRXFRAGSZ, TRUE, lbuf_rxfrag)) != BCME_OK) {
10621308 ASSERT(0);
10631309 goto error6;
10641310 }
10651311 pktpool_setmaxlen(pktpool_shared_rxlfrag, SHARED_RXFRAG_POOL_LEN);
1066
-#endif
1312
+#endif // endif
1313
+
1314
+#if defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED)
1315
+ /* Attach poolreorg module */
1316
+ if ((frwd_poolreorg_info = poolreorg_attach(osh,
1317
+#if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
1318
+ pktpool_shared_lfrag,
1319
+#else
1320
+ NULL,
1321
+#endif // endif
1322
+#if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
1323
+ pktpool_shared_rxlfrag,
1324
+#else
1325
+ NULL,
1326
+#endif // endif
1327
+ pktpool_shared)) == NULL) {
1328
+ ASSERT(0);
1329
+ goto error7;
1330
+ }
1331
+#endif /* defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED) */
10671332
10681333 pktpool_osh = osh;
1334
+ MALLOC_CLEAR_NOPERSIST(osh);
10691335
1070
- return;
1336
+ return BCME_OK;
1337
+
1338
+#if defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED)
1339
+ /* detach poolreorg module */
1340
+ poolreorg_detach(frwd_poolreorg_info);
1341
+error7:
1342
+#endif /* defined(BCMFRWDPOOLREORG) && !defined(BCMFRWDPOOLREORG_DISABLED) */
10711343
10721344 #if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
1345
+ pktpool_deinit(osh, pktpool_shared_rxlfrag);
10731346 error6:
1074
-#endif
1347
+#endif // endif
10751348
10761349 #if defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED)
10771350 pktpool_deinit(osh, pktpool_shared_lfrag);
10781351 error5:
1079
-#endif
1352
+#endif // endif
10801353
10811354 #if (defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)) || \
10821355 (defined(BCMFRAGPOOL) && !defined(BCMFRAGPOOL_DISABLED))
10831356 pktpool_deinit(osh, pktpool_shared);
1084
-#endif
1357
+#endif // endif
10851358
10861359 error4:
10871360 #if defined(BCMRXFRAGPOOL) && !defined(BCMRXFRAGPOOL_DISABLED)
....@@ -1101,19 +1374,36 @@
11011374
11021375 error1:
11031376 pktpool_dettach(osh);
1104
-}
1377
+error0:
1378
+ MALLOC_CLEAR_NOPERSIST(osh);
1379
+ return err;
1380
+} /* hnd_pktpool_init */
11051381
1106
-void
1382
+/** is called at each 'wl up' */
1383
+int
11071384 hnd_pktpool_fill(pktpool_t *pktpool, bool minimal)
11081385 {
1109
- pktpool_fill(pktpool_osh, pktpool, minimal);
1386
+ return (pktpool_fill(pktpool_osh, pktpool, minimal));
11101387 }
11111388
1112
-/* refill pktpools after reclaim */
1389
+/** refills pktpools after reclaim, is called once */
11131390 void
11141391 hnd_pktpool_refill(bool minimal)
11151392 {
11161393 if (POOL_ENAB(pktpool_shared)) {
1394
+#if defined(SRMEM)
1395
+ if (SRMEM_ENAB()) {
1396
+ int maxlen = pktpool_max_pkts(pktpool_shared);
1397
+ int n_pkts = pktpool_tot_pkts(pktpool_shared);
1398
+
1399
+ for (; n_pkts < maxlen; n_pkts++) {
1400
+ void *p;
1401
+ if ((p = PKTSRGET(pktpool_max_pkt_bytes(pktpool_shared))) == NULL)
1402
+ break;
1403
+ pktpool_add(pktpool_shared, p);
1404
+ }
1405
+ }
1406
+#endif /* SRMEM */
11171407 pktpool_fill(pktpool_osh, pktpool_shared, minimal);
11181408 }
11191409 /* fragpool reclaim */
....@@ -1127,6 +1417,13 @@
11271417 if (POOL_ENAB(pktpool_shared_rxlfrag)) {
11281418 pktpool_fill(pktpool_osh, pktpool_shared_rxlfrag, minimal);
11291419 }
1130
-#endif
1420
+#endif // endif
1421
+#if defined(BCMFRAGPOOL) && defined(BCMRESVFRAGPOOL)
1422
+ if (POOL_ENAB(pktpool_resv_lfrag)) {
1423
+ int resv_size = (PKTFRAGSZ + LBUFFRAGSZ)*RESV_FRAG_POOL_LEN;
1424
+ hnd_resv_pool_init(resv_pool_info, resv_size);
1425
+ hnd_resv_pool_enable(resv_pool_info);
1426
+ }
1427
+#endif /* BCMRESVFRAGPOOL */
11311428 }
11321429 #endif /* BCMPKTPOOL */