xref: /illumos-gate/usr/src/uts/common/io/bnxe/bnxe_rx.c (revision 55fea89d)
1d14abf15SRobert Mustacchi /*
2d14abf15SRobert Mustacchi  * CDDL HEADER START
3d14abf15SRobert Mustacchi  *
4d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
5d14abf15SRobert Mustacchi  * Common Development and Distribution License (the "License").
6d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
7d14abf15SRobert Mustacchi  *
8d14abf15SRobert Mustacchi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d14abf15SRobert Mustacchi  * or http://www.opensolaris.org/os/licensing.
10d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
11d14abf15SRobert Mustacchi  * and limitations under the License.
12d14abf15SRobert Mustacchi  *
13d14abf15SRobert Mustacchi  * When distributing Covered Code, include this CDDL HEADER in each
14d14abf15SRobert Mustacchi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d14abf15SRobert Mustacchi  * If applicable, add the following below this CDDL HEADER, with the
16d14abf15SRobert Mustacchi  * fields enclosed by brackets "[]" replaced with your own identifying
17d14abf15SRobert Mustacchi  * information: Portions Copyright [yyyy] [name of copyright owner]
18d14abf15SRobert Mustacchi  *
19d14abf15SRobert Mustacchi  * CDDL HEADER END
20d14abf15SRobert Mustacchi  */
21d14abf15SRobert Mustacchi 
22d14abf15SRobert Mustacchi /*
23d14abf15SRobert Mustacchi  * Copyright 2014 QLogic Corporation
24d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
25d14abf15SRobert Mustacchi  * QLogic End User License (the "License").
26d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
27d14abf15SRobert Mustacchi  *
28d14abf15SRobert Mustacchi  * You can obtain a copy of the License at
29d14abf15SRobert Mustacchi  * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
30d14abf15SRobert Mustacchi  * QLogic_End_User_Software_License.txt
31d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
32d14abf15SRobert Mustacchi  * and limitations under the License.
33d14abf15SRobert Mustacchi  */
34d14abf15SRobert Mustacchi 
35d14abf15SRobert Mustacchi /*
36d14abf15SRobert Mustacchi  * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
37d14abf15SRobert Mustacchi  */
38d14abf15SRobert Mustacchi 
39d14abf15SRobert Mustacchi #include "bnxe.h"
40d14abf15SRobert Mustacchi 
41d14abf15SRobert Mustacchi 
42d14abf15SRobert Mustacchi ddi_dma_attr_t bnxeRxDmaAttrib =
43d14abf15SRobert Mustacchi {
44d14abf15SRobert Mustacchi     DMA_ATTR_V0,         /* dma_attr_version */
45d14abf15SRobert Mustacchi     0,                   /* dma_attr_addr_lo */
46d14abf15SRobert Mustacchi     0xffffffffffffffff,  /* dma_attr_addr_hi */
47d14abf15SRobert Mustacchi     0xffffffffffffffff,  /* dma_attr_count_max */
48d14abf15SRobert Mustacchi     BNXE_DMA_ALIGNMENT,  /* dma_attr_align */
49d14abf15SRobert Mustacchi     0xffffffff,          /* dma_attr_burstsizes */
50d14abf15SRobert Mustacchi     1,                   /* dma_attr_minxfer */
51d14abf15SRobert Mustacchi     0xffffffffffffffff,  /* dma_attr_maxxfer */
52d14abf15SRobert Mustacchi     0xffffffffffffffff,  /* dma_attr_seg */
53d14abf15SRobert Mustacchi     1,                   /* dma_attr_sgllen */
54d14abf15SRobert Mustacchi     1,                   /* dma_attr_granular */
55d14abf15SRobert Mustacchi     0,                   /* dma_attr_flags */
56d14abf15SRobert Mustacchi };
57d14abf15SRobert Mustacchi 
58d14abf15SRobert Mustacchi 
BnxeRxPostBuffers(um_device_t * pUM,int idx,s_list_t * pReclaimList)59d14abf15SRobert Mustacchi static void BnxeRxPostBuffers(um_device_t * pUM,
60d14abf15SRobert Mustacchi                               int           idx,
61d14abf15SRobert Mustacchi                               s_list_t *    pReclaimList)
62d14abf15SRobert Mustacchi {
63d14abf15SRobert Mustacchi     lm_rx_chain_t * pLmRxChain = &LM_RXQ(&pUM->lm_dev, idx);
64d14abf15SRobert Mustacchi     u32_t           returnedBytes = 0;
65d14abf15SRobert Mustacchi     lm_packet_t *   pLmPkt;
66d14abf15SRobert Mustacchi 
67d14abf15SRobert Mustacchi     /* return bytes from reclaimed list to LM */
68d14abf15SRobert Mustacchi     pLmPkt = (lm_packet_t *)s_list_peek_head(pReclaimList);
69d14abf15SRobert Mustacchi     while (pLmPkt)
70d14abf15SRobert Mustacchi     {
71d14abf15SRobert Mustacchi         returnedBytes += pLmPkt->size;
72d14abf15SRobert Mustacchi         pLmPkt = (lm_packet_t *)s_list_next_entry(&pLmPkt->link);
73d14abf15SRobert Mustacchi     }
74d14abf15SRobert Mustacchi 
75d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_RX(pUM, idx);
76d14abf15SRobert Mustacchi 
77d14abf15SRobert Mustacchi     if (pUM->rxq[idx].rxLowWater > s_list_entry_cnt(&pLmRxChain->active_descq))
78d14abf15SRobert Mustacchi     {
79d14abf15SRobert Mustacchi         pUM->rxq[idx].rxLowWater = s_list_entry_cnt(&pLmRxChain->active_descq);
80d14abf15SRobert Mustacchi     }
81d14abf15SRobert Mustacchi 
82d14abf15SRobert Mustacchi     lm_return_packet_bytes(&pUM->lm_dev, idx, returnedBytes);
83d14abf15SRobert Mustacchi 
84d14abf15SRobert Mustacchi     s_list_add_tail(&pLmRxChain->common.free_descq, pReclaimList);
85d14abf15SRobert Mustacchi     s_list_clear(pReclaimList);
86d14abf15SRobert Mustacchi 
87d14abf15SRobert Mustacchi #if 0
88d14abf15SRobert Mustacchi     /*
89d14abf15SRobert Mustacchi      * Don't post buffers if we don't have too many free buffers and there are a
90d14abf15SRobert Mustacchi      * lot of buffers already posted.
91d14abf15SRobert Mustacchi      */
92d14abf15SRobert Mustacchi     if (lm_bd_chain_avail_bds(&pLmRxChain->bd_chain) < 32)
93d14abf15SRobert Mustacchi     {
94d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_RX(pUM, idx);
95d14abf15SRobert Mustacchi         return;
96d14abf15SRobert Mustacchi     }
97d14abf15SRobert Mustacchi 
98d14abf15SRobert Mustacchi     /*
99d14abf15SRobert Mustacchi      * Don't post buffers if there aren't really that many to post yet.
100d14abf15SRobert Mustacchi      */
101d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&pLmRxChain->common.free_descq) < 32)
102d14abf15SRobert Mustacchi     {
103d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_RX(pUM, idx);
104d14abf15SRobert Mustacchi         return;
105d14abf15SRobert Mustacchi     }
106d14abf15SRobert Mustacchi #endif
107d14abf15SRobert Mustacchi 
108d14abf15SRobert Mustacchi     lm_post_buffers(&pUM->lm_dev, idx, NULL, 0);
109d14abf15SRobert Mustacchi 
110d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_RX(pUM, idx);
111d14abf15SRobert Mustacchi }
112d14abf15SRobert Mustacchi 
113d14abf15SRobert Mustacchi 
BnxeRxPktDescrSize(um_device_t * pUM)114d14abf15SRobert Mustacchi static u32_t BnxeRxPktDescrSize(um_device_t * pUM)
115d14abf15SRobert Mustacchi {
116d14abf15SRobert Mustacchi     u32_t descSize;
117d14abf15SRobert Mustacchi 
118d14abf15SRobert Mustacchi     (void)pUM;
119d14abf15SRobert Mustacchi 
120d14abf15SRobert Mustacchi     descSize = sizeof(um_rxpacket_t) + SIZEOF_SIG;
121d14abf15SRobert Mustacchi 
122d14abf15SRobert Mustacchi     return ALIGN_VALUE_TO_WORD_BOUNDARY(descSize);
123d14abf15SRobert Mustacchi }
124d14abf15SRobert Mustacchi 
125d14abf15SRobert Mustacchi 
BnxeRxPktDescrFree(um_device_t * pUM,um_rxpacket_t * pRxPkt)126d14abf15SRobert Mustacchi static void BnxeRxPktDescrFree(um_device_t *   pUM,
127d14abf15SRobert Mustacchi                                um_rxpacket_t * pRxPkt)
128d14abf15SRobert Mustacchi {
129d14abf15SRobert Mustacchi     u32_t descSize;
130d14abf15SRobert Mustacchi     caddr_t pMem;
131d14abf15SRobert Mustacchi 
132d14abf15SRobert Mustacchi     BnxeDbgBreakIfFastPath(pUM, SIG(pRxPkt) != L2PACKET_RX_SIG);
133d14abf15SRobert Mustacchi 
134d14abf15SRobert Mustacchi     descSize = BnxeRxPktDescrSize(pUM);
135d14abf15SRobert Mustacchi     pMem = (caddr_t)pRxPkt - SIZEOF_SIG;
136d14abf15SRobert Mustacchi 
137d14abf15SRobert Mustacchi     kmem_free(pMem, descSize);
138d14abf15SRobert Mustacchi }
139d14abf15SRobert Mustacchi 
140d14abf15SRobert Mustacchi 
BnxeRxPktFree(char * free_arg)141d14abf15SRobert Mustacchi static void BnxeRxPktFree(char * free_arg)
142d14abf15SRobert Mustacchi {
143d14abf15SRobert Mustacchi     um_rxpacket_t * pRxPkt = (um_rxpacket_t *)free_arg;
144d14abf15SRobert Mustacchi     um_device_t *   pUM    = (um_device_t *)pRxPkt->pUM;
145d14abf15SRobert Mustacchi     int             idx    = pRxPkt->idx;
146d14abf15SRobert Mustacchi     s_list_t        doneRxQ;
147d14abf15SRobert Mustacchi 
148d14abf15SRobert Mustacchi     if (pUM->magic != BNXE_MAGIC)
149d14abf15SRobert Mustacchi     {
150d14abf15SRobert Mustacchi         /*
151d14abf15SRobert Mustacchi          * Oh my!  The free_arg data got corrupted.  Log a message and leak this
152d14abf15SRobert Mustacchi          * packet.  We don't decrement the 'up in the stack count' since we
153d14abf15SRobert Mustacchi          * can't be sure this packet really was a packet we previously sent up.
154d14abf15SRobert Mustacchi          */
155d14abf15SRobert Mustacchi         BnxeLogWarn(NULL, "ERROR freeing packet - UM is invalid! (%p)", pRxPkt);
156d14abf15SRobert Mustacchi         return;
157d14abf15SRobert Mustacchi     }
158d14abf15SRobert Mustacchi 
159d14abf15SRobert Mustacchi     if (pUM->rxBufSignature[LM_CHAIN_IDX_CLI(&pUM->lm_dev, idx)] !=
160d14abf15SRobert Mustacchi         pRxPkt->signature)
161d14abf15SRobert Mustacchi     {
162d14abf15SRobert Mustacchi         /*
163d14abf15SRobert Mustacchi          * The stack is freeing a packet that was from a previous plumb of
164d14abf15SRobert Mustacchi          * the interface.
165d14abf15SRobert Mustacchi          */
166d14abf15SRobert Mustacchi         pRxPkt->lm_pkt.u1.rx.mem_phys[0].as_u64 = 0;
167d14abf15SRobert Mustacchi         pRxPkt->rx_info.mem_virt = NULL;
168d14abf15SRobert Mustacchi         pRxPkt->rx_info.mem_size = 0;
169d14abf15SRobert Mustacchi 
170d14abf15SRobert Mustacchi         ddi_dma_unbind_handle(pRxPkt->dmaHandle);
171d14abf15SRobert Mustacchi         ddi_dma_mem_free(&pRxPkt->dmaAccHandle);
172d14abf15SRobert Mustacchi         ddi_dma_free_handle(&pRxPkt->dmaHandle);
173d14abf15SRobert Mustacchi 
174d14abf15SRobert Mustacchi         BnxeRxPktDescrFree(pUM, pRxPkt);
175d14abf15SRobert Mustacchi     }
176d14abf15SRobert Mustacchi     else
177d14abf15SRobert Mustacchi     {
178d14abf15SRobert Mustacchi         s_list_clear(&doneRxQ);
179d14abf15SRobert Mustacchi 
180d14abf15SRobert Mustacchi         BNXE_LOCK_ENTER_DONERX(pUM, idx);
181d14abf15SRobert Mustacchi 
182d14abf15SRobert Mustacchi         s_list_push_tail(&pUM->rxq[idx].doneRxQ,
183d14abf15SRobert Mustacchi                          &((lm_packet_t *)pRxPkt)->link);
184d14abf15SRobert Mustacchi 
185d14abf15SRobert Mustacchi         /* post packets when a bunch are ready */
186d14abf15SRobert Mustacchi         if (s_list_entry_cnt(&pUM->rxq[idx].doneRxQ) >= pUM->devParams.maxRxFree)
187d14abf15SRobert Mustacchi         {
188d14abf15SRobert Mustacchi             doneRxQ = pUM->rxq[idx].doneRxQ;
189d14abf15SRobert Mustacchi             s_list_clear(&pUM->rxq[idx].doneRxQ);
190d14abf15SRobert Mustacchi         }
191d14abf15SRobert Mustacchi 
192d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_DONERX(pUM, idx);
193d14abf15SRobert Mustacchi 
194d14abf15SRobert Mustacchi         if (s_list_entry_cnt(&doneRxQ))
195d14abf15SRobert Mustacchi         {
196d14abf15SRobert Mustacchi             BnxeRxPostBuffers(pUM, idx, &doneRxQ);
197d14abf15SRobert Mustacchi         }
198d14abf15SRobert Mustacchi     }
199d14abf15SRobert Mustacchi 
200d14abf15SRobert Mustacchi     atomic_dec_32(&pUM->rxq[idx].rxBufUpInStack);
201d14abf15SRobert Mustacchi }
202d14abf15SRobert Mustacchi 
203d14abf15SRobert Mustacchi 
BnxeWaitForPacketsFromClient(um_device_t * pUM,int cliIdx)204d14abf15SRobert Mustacchi boolean_t BnxeWaitForPacketsFromClient(um_device_t * pUM,
205d14abf15SRobert Mustacchi                                        int           cliIdx)
206d14abf15SRobert Mustacchi {
207d14abf15SRobert Mustacchi     int i, idx, cnt=0, tot=0;
208d14abf15SRobert Mustacchi 
209d14abf15SRobert Mustacchi     switch (cliIdx)
210d14abf15SRobert Mustacchi     {
211d14abf15SRobert Mustacchi     case LM_CLI_IDX_FCOE:
212d14abf15SRobert Mustacchi 
213d14abf15SRobert Mustacchi         for (i = 0; i < 5; i++)
214d14abf15SRobert Mustacchi         {
215d14abf15SRobert Mustacchi             if ((cnt = pUM->rxq[FCOE_CID(&pUM->lm_dev)].rxBufUpInStack) == 0)
216d14abf15SRobert Mustacchi             {
217d14abf15SRobert Mustacchi                 break;
218d14abf15SRobert Mustacchi             }
219d14abf15SRobert Mustacchi 
220d14abf15SRobert Mustacchi             /* twiddle our thumbs for one second */
221d14abf15SRobert Mustacchi             delay(drv_usectohz(1000000));
222d14abf15SRobert Mustacchi         }
223d14abf15SRobert Mustacchi 
224d14abf15SRobert Mustacchi         if (cnt)
225d14abf15SRobert Mustacchi         {
226d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "%d packets still held by FCoE (chain %d)!",
227d14abf15SRobert Mustacchi                         cnt, FCOE_CID(&pUM->lm_dev));
228d14abf15SRobert Mustacchi             return B_FALSE;
229d14abf15SRobert Mustacchi         }
230d14abf15SRobert Mustacchi 
231d14abf15SRobert Mustacchi         break;
232d14abf15SRobert Mustacchi 
233d14abf15SRobert Mustacchi     case LM_CLI_IDX_NDIS:
234d14abf15SRobert Mustacchi 
235d14abf15SRobert Mustacchi         tot = 0;
236d14abf15SRobert Mustacchi 
237d14abf15SRobert Mustacchi         LM_FOREACH_RSS_IDX(&pUM->lm_dev, idx)
238d14abf15SRobert Mustacchi         {
239d14abf15SRobert Mustacchi             for (i = 0; i < 5; i++)
240d14abf15SRobert Mustacchi             {
241d14abf15SRobert Mustacchi                 if ((cnt = pUM->rxq[idx].rxBufUpInStack) == 0)
242d14abf15SRobert Mustacchi                 {
243d14abf15SRobert Mustacchi                     break;
244d14abf15SRobert Mustacchi                 }
245d14abf15SRobert Mustacchi 
246d14abf15SRobert Mustacchi                 /* twiddle our thumbs for one second */
247d14abf15SRobert Mustacchi                 delay(drv_usectohz(1000000));
248d14abf15SRobert Mustacchi             }
249d14abf15SRobert Mustacchi 
250d14abf15SRobert Mustacchi             tot += cnt;
251d14abf15SRobert Mustacchi         }
252d14abf15SRobert Mustacchi 
253d14abf15SRobert Mustacchi         if (tot)
254d14abf15SRobert Mustacchi         {
255d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "%d packets still held by the stack (chain %d)!",
256d14abf15SRobert Mustacchi                         tot, idx);
257d14abf15SRobert Mustacchi             return B_FALSE;
258d14abf15SRobert Mustacchi         }
259d14abf15SRobert Mustacchi 
260d14abf15SRobert Mustacchi         break;
261d14abf15SRobert Mustacchi 
262d14abf15SRobert Mustacchi     default:
263d14abf15SRobert Mustacchi 
264d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "ERROR: Invalid cliIdx for BnxeWaitForPacketsFromClient (%d)", cliIdx);
265d14abf15SRobert Mustacchi         break;
266d14abf15SRobert Mustacchi     }
267d14abf15SRobert Mustacchi 
268d14abf15SRobert Mustacchi     return B_TRUE;
269d14abf15SRobert Mustacchi }
270d14abf15SRobert Mustacchi 
271d14abf15SRobert Mustacchi 
272d14abf15SRobert Mustacchi /* numBytes is only valid when polling is TRUE */
BnxeRxRingProcess(um_device_t * pUM,int idx,boolean_t polling,int numBytes)273d14abf15SRobert Mustacchi mblk_t * BnxeRxRingProcess(um_device_t * pUM,
274d14abf15SRobert Mustacchi                            int           idx,
275d14abf15SRobert Mustacchi                            boolean_t     polling,
276d14abf15SRobert Mustacchi                            int           numBytes)
277d14abf15SRobert Mustacchi {
278d14abf15SRobert Mustacchi     RxQueue *       pRxQ;
279d14abf15SRobert Mustacchi     lm_rx_chain_t * pLmRxChain;
280d14abf15SRobert Mustacchi     u32_t           activeDescqCount;
281d14abf15SRobert Mustacchi     boolean_t       forceCopy;
282d14abf15SRobert Mustacchi     um_rxpacket_t * pRxPkt;
283d14abf15SRobert Mustacchi     lm_packet_t *   pLmPkt;
284d14abf15SRobert Mustacchi     u32_t           pktLen;
285d14abf15SRobert Mustacchi     boolean_t       dataCopied;
286d14abf15SRobert Mustacchi     u32_t           notCopiedCount;
287d14abf15SRobert Mustacchi     mblk_t *        pMblk;
288d14abf15SRobert Mustacchi     int             ofldFlags;
289d14abf15SRobert Mustacchi     mblk_t *        head = NULL;
290d14abf15SRobert Mustacchi     mblk_t *        tail = NULL;
291d14abf15SRobert Mustacchi     s_list_t        rxList;
292d14abf15SRobert Mustacchi     s_list_t        reclaimList;
293d14abf15SRobert Mustacchi     int             procBytes = 0;
294d14abf15SRobert Mustacchi     s_list_t        tmpList;
295d14abf15SRobert Mustacchi     sp_cqes_info    sp_cqes;
296d14abf15SRobert Mustacchi     u32_t           pktsRxed;
297d14abf15SRobert Mustacchi 
298d14abf15SRobert Mustacchi     pRxQ = &pUM->rxq[idx];
299d14abf15SRobert Mustacchi 
300d14abf15SRobert Mustacchi     s_list_clear(&tmpList);
301d14abf15SRobert Mustacchi 
302d14abf15SRobert Mustacchi     /* get the list of packets received */
303d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_RX(pUM, idx);
304d14abf15SRobert Mustacchi 
305d14abf15SRobert Mustacchi     pktsRxed = lm_get_packets_rcvd(&pUM->lm_dev, idx, &tmpList, &sp_cqes);
306d14abf15SRobert Mustacchi 
307d14abf15SRobert Mustacchi     /* grab any waiting packets */
308d14abf15SRobert Mustacchi     rxList = pRxQ->waitRxQ;
309d14abf15SRobert Mustacchi     s_list_clear(&pRxQ->waitRxQ);
310d14abf15SRobert Mustacchi 
311d14abf15SRobert Mustacchi     /* put any new packets at the end of the queue */
312d14abf15SRobert Mustacchi     s_list_add_tail(&rxList, &tmpList);
313d14abf15SRobert Mustacchi 
314d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_RX(pUM, idx);
315d14abf15SRobert Mustacchi 
316d14abf15SRobert Mustacchi     /* now complete the ramrods */
317d14abf15SRobert Mustacchi     lm_complete_ramrods(&pUM->lm_dev, &sp_cqes);
318d14abf15SRobert Mustacchi 
319d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&rxList) == 0)
320d14abf15SRobert Mustacchi     {
321d14abf15SRobert Mustacchi         return NULL;
322d14abf15SRobert Mustacchi     }
323d14abf15SRobert Mustacchi 
324d14abf15SRobert Mustacchi     s_list_clear(&reclaimList);
325d14abf15SRobert Mustacchi     notCopiedCount = 0;
326d14abf15SRobert Mustacchi 
327d14abf15SRobert Mustacchi     pLmRxChain = &LM_RXQ(&pUM->lm_dev, idx);
328d14abf15SRobert Mustacchi 
329d14abf15SRobert Mustacchi     activeDescqCount = s_list_entry_cnt(&pLmRxChain->active_descq);
330d14abf15SRobert Mustacchi 
331d14abf15SRobert Mustacchi     forceCopy = (activeDescqCount <
332d14abf15SRobert Mustacchi                  (pUM->lm_dev.params.l2_rx_desc_cnt[LM_CHAIN_IDX_CLI(&pUM->lm_dev, idx)] >> 3));
333d14abf15SRobert Mustacchi 
334d14abf15SRobert Mustacchi     /* send the packets up the stack */
335d14abf15SRobert Mustacchi     while (1)
336d14abf15SRobert Mustacchi     {
337d14abf15SRobert Mustacchi         pRxPkt = (um_rxpacket_t *)s_list_pop_head(&rxList);
338d14abf15SRobert Mustacchi         if (pRxPkt == NULL)
339d14abf15SRobert Mustacchi         {
340d14abf15SRobert Mustacchi             break;
341d14abf15SRobert Mustacchi         }
342d14abf15SRobert Mustacchi 
343d14abf15SRobert Mustacchi         pLmPkt = &(pRxPkt->lm_pkt);
344d14abf15SRobert Mustacchi 
345d14abf15SRobert Mustacchi         if (pLmPkt->status != LM_STATUS_SUCCESS)
346d14abf15SRobert Mustacchi         {
347d14abf15SRobert Mustacchi             /* XXX increment error stat? */
348d14abf15SRobert Mustacchi             s_list_push_tail(&reclaimList, &pLmPkt->link);
349d14abf15SRobert Mustacchi             continue;
350d14abf15SRobert Mustacchi         }
351d14abf15SRobert Mustacchi 
352d14abf15SRobert Mustacchi         pktLen = pLmPkt->size;
353d14abf15SRobert Mustacchi 
354d14abf15SRobert Mustacchi         if (polling == TRUE)
355d14abf15SRobert Mustacchi         {
356d14abf15SRobert Mustacchi             /* When polling an rx ring we can only process up to numBytes */
357d14abf15SRobert Mustacchi             if ((procBytes + pktLen) <= numBytes)
358d14abf15SRobert Mustacchi             {
359d14abf15SRobert Mustacchi                 /* continue to process this packet */
360d14abf15SRobert Mustacchi                 procBytes += pktLen;
361d14abf15SRobert Mustacchi             }
362d14abf15SRobert Mustacchi             else
363d14abf15SRobert Mustacchi             {
364d14abf15SRobert Mustacchi                 /* put this packet not processed back on the list (front) */
365d14abf15SRobert Mustacchi                 s_list_push_head(&rxList, &pRxPkt->lm_pkt.link);
366d14abf15SRobert Mustacchi                 break;
367d14abf15SRobert Mustacchi             }
368d14abf15SRobert Mustacchi         }
369d14abf15SRobert Mustacchi 
370d14abf15SRobert Mustacchi         (void)ddi_dma_sync(pRxPkt->dmaHandle,
371d14abf15SRobert Mustacchi                            0,
372d14abf15SRobert Mustacchi                            pktLen,
373d14abf15SRobert Mustacchi                            DDI_DMA_SYNC_FORKERNEL);
374d14abf15SRobert Mustacchi 
375d14abf15SRobert Mustacchi         if (pUM->fmCapabilities &&
376d14abf15SRobert Mustacchi             BnxeCheckDmaHandle(pRxPkt->dmaHandle) != DDI_FM_OK)
377d14abf15SRobert Mustacchi         {
378d14abf15SRobert Mustacchi             ddi_fm_service_impact(pUM->pDev, DDI_SERVICE_DEGRADED);
379d14abf15SRobert Mustacchi         }
380d14abf15SRobert Mustacchi 
381d14abf15SRobert Mustacchi         dataCopied = B_FALSE;
382d14abf15SRobert Mustacchi 
383d14abf15SRobert Mustacchi         if (forceCopy ||
384d14abf15SRobert Mustacchi             (pUM->devParams.rxCopyThreshold &&
385d14abf15SRobert Mustacchi              (pktLen < pUM->devParams.rxCopyThreshold)))
386d14abf15SRobert Mustacchi         {
387d14abf15SRobert Mustacchi             if ((pMblk = allocb(pktLen, BPRI_MED)) == NULL)
388d14abf15SRobert Mustacchi             {
389d14abf15SRobert Mustacchi                 pRxQ->rxDiscards++;
390d14abf15SRobert Mustacchi                 s_list_push_tail(&reclaimList, &pLmPkt->link);
391d14abf15SRobert Mustacchi                 continue;
392d14abf15SRobert Mustacchi             }
393d14abf15SRobert Mustacchi 
394d14abf15SRobert Mustacchi             /* copy the packet into the new mblk */
395d14abf15SRobert Mustacchi             bcopy((pRxPkt->rx_info.mem_virt + BNXE_DMA_RX_OFFSET),
396d14abf15SRobert Mustacchi                   pMblk->b_rptr, pktLen);
397d14abf15SRobert Mustacchi             pMblk->b_wptr = (pMblk->b_rptr + pktLen);
398d14abf15SRobert Mustacchi             dataCopied = B_TRUE;
399d14abf15SRobert Mustacchi 
400d14abf15SRobert Mustacchi             pRxQ->rxCopied++;
401d14abf15SRobert Mustacchi 
402d14abf15SRobert Mustacchi             goto BnxeRxRingProcess_sendup;
403d14abf15SRobert Mustacchi         }
404d14abf15SRobert Mustacchi 
405d14abf15SRobert Mustacchi         if ((activeDescqCount == 0) && (s_list_entry_cnt(&rxList) == 0))
406d14abf15SRobert Mustacchi         {
407d14abf15SRobert Mustacchi             /*
408d14abf15SRobert Mustacchi              * If the hardware is out of receive buffers and we are on the last
409d14abf15SRobert Mustacchi              * receive packet then drop the packet.  We do this because we might
410d14abf15SRobert Mustacchi              * not be able to allocate any new receive buffers before the ISR
411d14abf15SRobert Mustacchi              * completes.  If this happens, the driver will enter an infinite
412d14abf15SRobert Mustacchi              * interrupt loop where the hardware is requesting rx buffers the
413d14abf15SRobert Mustacchi              * driver cannot allocate.  To prevent a system livelock we leave
414d14abf15SRobert Mustacchi              * one buffer perpetually available.  Note that we do this after
415d14abf15SRobert Mustacchi              * giving the double copy code a chance to claim the packet.
416d14abf15SRobert Mustacchi              */
417d14abf15SRobert Mustacchi 
418d14abf15SRobert Mustacchi             /* FIXME
419d14abf15SRobert Mustacchi              * Make sure to add one more to the rx packet descriptor count
420d14abf15SRobert Mustacchi              * before allocating them.
421d14abf15SRobert Mustacchi              */
422d14abf15SRobert Mustacchi 
423d14abf15SRobert Mustacchi             pRxQ->rxDiscards++;
424d14abf15SRobert Mustacchi             s_list_push_tail(&reclaimList, &pLmPkt->link);
425d14abf15SRobert Mustacchi             continue;
426d14abf15SRobert Mustacchi         }
427d14abf15SRobert Mustacchi 
428d14abf15SRobert Mustacchi         /*
429d14abf15SRobert Mustacchi          * If we got here then the packet wasn't copied so we need to create a
430d14abf15SRobert Mustacchi          * new mblk_t which references the lm_packet_t buffer.
431d14abf15SRobert Mustacchi          */
432d14abf15SRobert Mustacchi 
433d14abf15SRobert Mustacchi         pRxPkt->freeRtn.free_func = BnxeRxPktFree;
434d14abf15SRobert Mustacchi         pRxPkt->freeRtn.free_arg  = (char *)pRxPkt;
435d14abf15SRobert Mustacchi         pRxPkt->pUM               = (void *)pUM;
436d14abf15SRobert Mustacchi         pRxPkt->idx               = idx;
437d14abf15SRobert Mustacchi 
438d14abf15SRobert Mustacchi         if ((pMblk = desballoc((pRxPkt->rx_info.mem_virt + BNXE_DMA_RX_OFFSET),
439d14abf15SRobert Mustacchi                                pktLen,
440d14abf15SRobert Mustacchi                                BPRI_MED,
441d14abf15SRobert Mustacchi                                &pRxPkt->freeRtn)) == NULL)
442d14abf15SRobert Mustacchi         {
443d14abf15SRobert Mustacchi             pRxQ->rxDiscards++;
444d14abf15SRobert Mustacchi             s_list_push_tail(&reclaimList, &pLmPkt->link);
445d14abf15SRobert Mustacchi             continue;
446d14abf15SRobert Mustacchi         }
447d14abf15SRobert Mustacchi 
448d14abf15SRobert Mustacchi         pMblk->b_wptr = (pMblk->b_rptr + pktLen);
449d14abf15SRobert Mustacchi 
450d14abf15SRobert Mustacchi BnxeRxRingProcess_sendup:
451d14abf15SRobert Mustacchi 
452d14abf15SRobert Mustacchi         /*
453d14abf15SRobert Mustacchi          * Check if the checksum was offloaded so we can pass the result to
454d14abf15SRobert Mustacchi          * the stack.
455d14abf15SRobert Mustacchi          */
456d14abf15SRobert Mustacchi         ofldFlags = 0;
457d14abf15SRobert Mustacchi 
458d14abf15SRobert Mustacchi         if ((pUM->devParams.enabled_oflds & LM_OFFLOAD_RX_IP_CKSUM) &&
459d14abf15SRobert Mustacchi             (pRxPkt->rx_info.flags & LM_RX_FLAG_IP_CKSUM_IS_GOOD))
460d14abf15SRobert Mustacchi         {
461d14abf15SRobert Mustacchi             ofldFlags |= HCK_IPV4_HDRCKSUM_OK;
462d14abf15SRobert Mustacchi         }
463d14abf15SRobert Mustacchi 
464d14abf15SRobert Mustacchi         if (((pUM->devParams.enabled_oflds & LM_OFFLOAD_RX_TCP_CKSUM) &&
465d14abf15SRobert Mustacchi              (pRxPkt->rx_info.flags & LM_RX_FLAG_TCP_CKSUM_IS_GOOD)) ||
466d14abf15SRobert Mustacchi             ((pUM->devParams.enabled_oflds & LM_OFFLOAD_RX_UDP_CKSUM) &&
467d14abf15SRobert Mustacchi              (pRxPkt->rx_info.flags & LM_RX_FLAG_UDP_CKSUM_IS_GOOD)))
468d14abf15SRobert Mustacchi         {
469d14abf15SRobert Mustacchi             ofldFlags |= HCK_FULLCKSUM_OK;
470d14abf15SRobert Mustacchi         }
471d14abf15SRobert Mustacchi 
472d14abf15SRobert Mustacchi         if (ofldFlags != 0)
473d14abf15SRobert Mustacchi         {
474d14abf15SRobert Mustacchi             mac_hcksum_set(pMblk, 0, 0, 0, 0, ofldFlags);
475d14abf15SRobert Mustacchi         }
476d14abf15SRobert Mustacchi 
477d14abf15SRobert Mustacchi         /*
478d14abf15SRobert Mustacchi          * If the packet data was copied into a new recieve buffer then put this
479d14abf15SRobert Mustacchi          * descriptor in a list to be reclaimed later.  If not, then increment a
480d14abf15SRobert Mustacchi          * counter so we can track how many of our descriptors are held by the
481d14abf15SRobert Mustacchi          * stack.
482d14abf15SRobert Mustacchi          */
483d14abf15SRobert Mustacchi         if (dataCopied == B_TRUE)
484d14abf15SRobert Mustacchi         {
485d14abf15SRobert Mustacchi             s_list_push_tail(&reclaimList, &pLmPkt->link);
486d14abf15SRobert Mustacchi         }
487d14abf15SRobert Mustacchi         else
488d14abf15SRobert Mustacchi         {
489d14abf15SRobert Mustacchi             notCopiedCount++;
490d14abf15SRobert Mustacchi         }
491d14abf15SRobert Mustacchi 
492d14abf15SRobert Mustacchi         if (head == NULL)
493d14abf15SRobert Mustacchi         {
494d14abf15SRobert Mustacchi             head = pMblk;
495d14abf15SRobert Mustacchi         }
496d14abf15SRobert Mustacchi         else
497d14abf15SRobert Mustacchi         {
498d14abf15SRobert Mustacchi             tail->b_next = pMblk;
499d14abf15SRobert Mustacchi         }
500d14abf15SRobert Mustacchi 
501d14abf15SRobert Mustacchi         tail         = pMblk;
502d14abf15SRobert Mustacchi         tail->b_next = NULL;
503d14abf15SRobert Mustacchi 
504d14abf15SRobert Mustacchi #if 0
505*55fea89dSDan Cross         BnxeDumpPkt(pUM,
506d14abf15SRobert Mustacchi                     (BNXE_FCOE(pUM) && (idx == FCOE_CID(&pUM->lm_dev))) ?
507d14abf15SRobert Mustacchi                         "<- FCoE L2 RX <-" : "<- L2 RX <-",
508d14abf15SRobert Mustacchi                     pMblk, B_TRUE);
509d14abf15SRobert Mustacchi #endif
510d14abf15SRobert Mustacchi     }
511d14abf15SRobert Mustacchi 
512d14abf15SRobert Mustacchi     if (head)
513d14abf15SRobert Mustacchi     {
514d14abf15SRobert Mustacchi         if (notCopiedCount)
515d14abf15SRobert Mustacchi         {
516d14abf15SRobert Mustacchi             /* track all non-copied packets that will be held by the stack */
517d14abf15SRobert Mustacchi             atomic_add_32(&pUM->rxq[idx].rxBufUpInStack, notCopiedCount);
518d14abf15SRobert Mustacchi         }
519d14abf15SRobert Mustacchi 
520d14abf15SRobert Mustacchi         /* pass the mblk chain up the stack */
521d14abf15SRobert Mustacchi         if (polling == FALSE)
522d14abf15SRobert Mustacchi         {
523d14abf15SRobert Mustacchi 
524d14abf15SRobert Mustacchi /* XXX NEED TO ADD STATS FOR RX PATH UPCALLS */
525d14abf15SRobert Mustacchi 
526d14abf15SRobert Mustacchi             if (BNXE_FCOE(pUM) && (idx == FCOE_CID(&pUM->lm_dev)))
527d14abf15SRobert Mustacchi             {
528d14abf15SRobert Mustacchi                 /* XXX verify fcoe frees all packets on success or error */
529d14abf15SRobert Mustacchi                 if (pUM->fcoe.pDev && pUM->fcoe.bind.cliIndicateRx)
530d14abf15SRobert Mustacchi                 {
531d14abf15SRobert Mustacchi                     pUM->fcoe.bind.cliIndicateRx(pUM->fcoe.pDev, head);
532d14abf15SRobert Mustacchi                 }
533d14abf15SRobert Mustacchi                 else
534d14abf15SRobert Mustacchi                 {
535d14abf15SRobert Mustacchi                     /* FCoE isn't bound?  Reclaim the chain... */
536d14abf15SRobert Mustacchi                     freemsgchain(head);
537d14abf15SRobert Mustacchi                     head = NULL;
538d14abf15SRobert Mustacchi                 }
539d14abf15SRobert Mustacchi             }
540d14abf15SRobert Mustacchi             else
541d14abf15SRobert Mustacchi             {
542d14abf15SRobert Mustacchi #if defined(BNXE_RINGS) && (defined(__S11) || defined(__S12))
543d14abf15SRobert Mustacchi                 mac_rx_ring(pUM->pMac,
544d14abf15SRobert Mustacchi                             pUM->rxq[idx].ringHandle,
545d14abf15SRobert Mustacchi                             head,
546d14abf15SRobert Mustacchi                             pUM->rxq[idx].genNumber);
547d14abf15SRobert Mustacchi #else
548d14abf15SRobert Mustacchi                 mac_rx(pUM->pMac,
549d14abf15SRobert Mustacchi                        pUM->macRxResourceHandles[idx],
550d14abf15SRobert Mustacchi                        head);
551d14abf15SRobert Mustacchi #endif
552d14abf15SRobert Mustacchi             }
553d14abf15SRobert Mustacchi         }
554d14abf15SRobert Mustacchi     }
555d14abf15SRobert Mustacchi 
556d14abf15SRobert Mustacchi     if ((polling == TRUE) && s_list_entry_cnt(&rxList))
557d14abf15SRobert Mustacchi     {
558d14abf15SRobert Mustacchi         /* put the packets not processed back on the list (front) */
559d14abf15SRobert Mustacchi         BNXE_LOCK_ENTER_RX(pUM, idx);
560d14abf15SRobert Mustacchi         s_list_add_head(&pRxQ->waitRxQ, &rxList);
561d14abf15SRobert Mustacchi         BNXE_LOCK_EXIT_RX(pUM, idx);
562d14abf15SRobert Mustacchi     }
563d14abf15SRobert Mustacchi 
564d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&reclaimList))
565d14abf15SRobert Mustacchi     {
566d14abf15SRobert Mustacchi         BnxeRxPostBuffers(pUM, idx, &reclaimList);
567d14abf15SRobert Mustacchi     }
568d14abf15SRobert Mustacchi 
569d14abf15SRobert Mustacchi     return (polling == TRUE) ? head : NULL;
570d14abf15SRobert Mustacchi }
571d14abf15SRobert Mustacchi 
572d14abf15SRobert Mustacchi 
573d14abf15SRobert Mustacchi /*
574d14abf15SRobert Mustacchi  * Dumping packets simply moves all packets from the waiting queue to the free
575d14abf15SRobert Mustacchi  * queue.  Note that the packets are not posted back to the LM.
576d14abf15SRobert Mustacchi  */
BnxeRxRingDump(um_device_t * pUM,int idx)577d14abf15SRobert Mustacchi static void BnxeRxRingDump(um_device_t * pUM,
578d14abf15SRobert Mustacchi                            int           idx)
579d14abf15SRobert Mustacchi {
580d14abf15SRobert Mustacchi     s_list_t tmpList;
581d14abf15SRobert Mustacchi 
582d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_RX(pUM, idx);
583d14abf15SRobert Mustacchi 
584d14abf15SRobert Mustacchi     tmpList = pUM->rxq[idx].waitRxQ;
585d14abf15SRobert Mustacchi     s_list_clear(&pUM->rxq[idx].waitRxQ);
586d14abf15SRobert Mustacchi 
587d14abf15SRobert Mustacchi     s_list_add_tail(&LM_RXQ(&pUM->lm_dev, idx).common.free_descq, &tmpList);
588d14abf15SRobert Mustacchi 
589d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_RX(pUM, idx);
590d14abf15SRobert Mustacchi }
591d14abf15SRobert Mustacchi 
592d14abf15SRobert Mustacchi 
593d14abf15SRobert Mustacchi /*
594d14abf15SRobert Mustacchi  * Aborting packets stops all rx processing by dumping the currently waiting
595d14abf15SRobert Mustacchi  * packets and aborting all the rx descriptors currently posted in the LM.
596d14abf15SRobert Mustacchi  */
BnxeRxPktsAbortIdx(um_device_t * pUM,int idx)597d14abf15SRobert Mustacchi static void BnxeRxPktsAbortIdx(um_device_t * pUM,
598d14abf15SRobert Mustacchi                                int           idx)
599d14abf15SRobert Mustacchi {
600d14abf15SRobert Mustacchi     BnxeRxRingDump(pUM, idx);
601d14abf15SRobert Mustacchi 
602d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_RX(pUM, idx);
603d14abf15SRobert Mustacchi     lm_abort(&pUM->lm_dev, ABORT_OP_RX_CHAIN, idx);
604d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_RX(pUM, idx);
605d14abf15SRobert Mustacchi }
606d14abf15SRobert Mustacchi 
607d14abf15SRobert Mustacchi 
BnxeRxPktsAbort(um_device_t * pUM,int cliIdx)608d14abf15SRobert Mustacchi void BnxeRxPktsAbort(um_device_t * pUM,
609d14abf15SRobert Mustacchi                      int           cliIdx)
610d14abf15SRobert Mustacchi {
611d14abf15SRobert Mustacchi     int idx;
612d14abf15SRobert Mustacchi 
613d14abf15SRobert Mustacchi     switch (cliIdx)
614d14abf15SRobert Mustacchi     {
615d14abf15SRobert Mustacchi     case LM_CLI_IDX_FCOE:
616d14abf15SRobert Mustacchi 
617d14abf15SRobert Mustacchi         BnxeRxPktsAbortIdx(pUM, FCOE_CID(&pUM->lm_dev));
618d14abf15SRobert Mustacchi         break;
619d14abf15SRobert Mustacchi 
620d14abf15SRobert Mustacchi     case LM_CLI_IDX_NDIS:
621d14abf15SRobert Mustacchi 
622d14abf15SRobert Mustacchi         LM_FOREACH_RSS_IDX(&pUM->lm_dev, idx)
623d14abf15SRobert Mustacchi         {
624d14abf15SRobert Mustacchi             BnxeRxPktsAbortIdx(pUM, idx);
625d14abf15SRobert Mustacchi         }
626d14abf15SRobert Mustacchi 
627d14abf15SRobert Mustacchi         break;
628d14abf15SRobert Mustacchi 
629d14abf15SRobert Mustacchi     default:
630d14abf15SRobert Mustacchi 
631d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "ERROR: Invalid cliIdx for BnxeRxPktsAbort (%d)", cliIdx);
632d14abf15SRobert Mustacchi         break;
633d14abf15SRobert Mustacchi     }
634d14abf15SRobert Mustacchi }
635d14abf15SRobert Mustacchi 
636d14abf15SRobert Mustacchi 
BnxeRxBufAlloc(um_device_t * pUM,int idx,um_rxpacket_t * pRxPkt)637d14abf15SRobert Mustacchi static int BnxeRxBufAlloc(um_device_t *   pUM,
638d14abf15SRobert Mustacchi                           int             idx,
639d14abf15SRobert Mustacchi                           um_rxpacket_t * pRxPkt)
640d14abf15SRobert Mustacchi {
641d14abf15SRobert Mustacchi     ddi_dma_cookie_t cookie;
642d14abf15SRobert Mustacchi     u32_t            count;
643d14abf15SRobert Mustacchi     size_t           length;
644d14abf15SRobert Mustacchi     int rc;
645d14abf15SRobert Mustacchi 
646d14abf15SRobert Mustacchi     if ((rc = ddi_dma_alloc_handle(pUM->pDev,
647d14abf15SRobert Mustacchi                                    &bnxeRxDmaAttrib,
648d14abf15SRobert Mustacchi                                    DDI_DMA_DONTWAIT,
649d14abf15SRobert Mustacchi                                    NULL,
650d14abf15SRobert Mustacchi                                    &pRxPkt->dmaHandle)) != DDI_SUCCESS)
651d14abf15SRobert Mustacchi     {
652d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to alloc DMA handle for rx buffer");
653d14abf15SRobert Mustacchi         return -1;
654d14abf15SRobert Mustacchi     }
655d14abf15SRobert Mustacchi 
656d14abf15SRobert Mustacchi     pRxPkt->rx_info.mem_size = MAX_L2_CLI_BUFFER_SIZE(&pUM->lm_dev, idx);
657d14abf15SRobert Mustacchi 
658d14abf15SRobert Mustacchi     if ((rc = ddi_dma_mem_alloc(pRxPkt->dmaHandle,
659d14abf15SRobert Mustacchi                                 pRxPkt->rx_info.mem_size,
660d14abf15SRobert Mustacchi                                 &bnxeAccessAttribBUF,
661d14abf15SRobert Mustacchi                                 DDI_DMA_STREAMING,
662d14abf15SRobert Mustacchi                                 DDI_DMA_DONTWAIT,
663d14abf15SRobert Mustacchi                                 NULL,
664d14abf15SRobert Mustacchi                                 (caddr_t *)&pRxPkt->rx_info.mem_virt,
665d14abf15SRobert Mustacchi                                 &length,
666d14abf15SRobert Mustacchi                                 &pRxPkt->dmaAccHandle)) != DDI_SUCCESS)
667d14abf15SRobert Mustacchi     {
668d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to alloc DMA memory for rx buffer");
669d14abf15SRobert Mustacchi         ddi_dma_free_handle(&pRxPkt->dmaHandle);
670d14abf15SRobert Mustacchi         return -1;
671d14abf15SRobert Mustacchi     }
672d14abf15SRobert Mustacchi 
673d14abf15SRobert Mustacchi     if ((rc = ddi_dma_addr_bind_handle(pRxPkt->dmaHandle,
674d14abf15SRobert Mustacchi                                        NULL,
675d14abf15SRobert Mustacchi                                        (caddr_t)pRxPkt->rx_info.mem_virt,
676d14abf15SRobert Mustacchi                                        pRxPkt->rx_info.mem_size,
677d14abf15SRobert Mustacchi                                        DDI_DMA_READ | DDI_DMA_STREAMING,
678d14abf15SRobert Mustacchi                                        DDI_DMA_DONTWAIT,
679d14abf15SRobert Mustacchi                                        NULL,
680d14abf15SRobert Mustacchi                                        &cookie,
681d14abf15SRobert Mustacchi                                        &count)) != DDI_DMA_MAPPED)
682d14abf15SRobert Mustacchi     {
683d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to bind DMA address for rx buffer");
684d14abf15SRobert Mustacchi         ddi_dma_mem_free(&pRxPkt->dmaAccHandle);
685d14abf15SRobert Mustacchi         ddi_dma_free_handle(&pRxPkt->dmaHandle);
686d14abf15SRobert Mustacchi         return -1;
687d14abf15SRobert Mustacchi     }
688d14abf15SRobert Mustacchi 
689d14abf15SRobert Mustacchi     pRxPkt->lm_pkt.u1.rx.mem_phys[0].as_u64 = cookie.dmac_laddress;
690d14abf15SRobert Mustacchi 
691d14abf15SRobert Mustacchi     return 0;
692d14abf15SRobert Mustacchi }
693d14abf15SRobert Mustacchi 
694d14abf15SRobert Mustacchi 
BnxeRxPktsInitPostBuffersIdx(um_device_t * pUM,int idx)695d14abf15SRobert Mustacchi static int BnxeRxPktsInitPostBuffersIdx(um_device_t * pUM,
696d14abf15SRobert Mustacchi                                         int           idx)
697d14abf15SRobert Mustacchi {
698d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_RX(pUM, idx);
699d14abf15SRobert Mustacchi     lm_post_buffers(&pUM->lm_dev, idx, NULL, 0);
700d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_RX(pUM, idx);
701d14abf15SRobert Mustacchi 
702d14abf15SRobert Mustacchi     return 0;
703d14abf15SRobert Mustacchi }
704d14abf15SRobert Mustacchi 
705d14abf15SRobert Mustacchi 
BnxeRxPktsInitPostBuffers(um_device_t * pUM,int cliIdx)706d14abf15SRobert Mustacchi int BnxeRxPktsInitPostBuffers(um_device_t * pUM,
707d14abf15SRobert Mustacchi                               int           cliIdx)
708d14abf15SRobert Mustacchi {
709d14abf15SRobert Mustacchi     int idx;
710d14abf15SRobert Mustacchi 
711d14abf15SRobert Mustacchi     switch (cliIdx)
712d14abf15SRobert Mustacchi     {
713d14abf15SRobert Mustacchi     case LM_CLI_IDX_FCOE:
714d14abf15SRobert Mustacchi 
715d14abf15SRobert Mustacchi         BnxeRxPktsInitPostBuffersIdx(pUM, FCOE_CID(&pUM->lm_dev));
716d14abf15SRobert Mustacchi         break;
717d14abf15SRobert Mustacchi 
718d14abf15SRobert Mustacchi     case LM_CLI_IDX_NDIS:
719d14abf15SRobert Mustacchi 
720d14abf15SRobert Mustacchi         LM_FOREACH_RSS_IDX(&pUM->lm_dev, idx)
721d14abf15SRobert Mustacchi         {
722d14abf15SRobert Mustacchi             BnxeRxPktsInitPostBuffersIdx(pUM, idx);
723d14abf15SRobert Mustacchi         }
724d14abf15SRobert Mustacchi 
725d14abf15SRobert Mustacchi         break;
726d14abf15SRobert Mustacchi 
727d14abf15SRobert Mustacchi     default:
728d14abf15SRobert Mustacchi 
729d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "ERROR: Invalid cliIdx for BnxeRxPktsInit (%d)", cliIdx);
730d14abf15SRobert Mustacchi         break;
731d14abf15SRobert Mustacchi     }
732d14abf15SRobert Mustacchi 
733d14abf15SRobert Mustacchi     return 0;
734d14abf15SRobert Mustacchi }
735d14abf15SRobert Mustacchi 
736d14abf15SRobert Mustacchi 
BnxeRxPktsInitIdx(um_device_t * pUM,int idx)737d14abf15SRobert Mustacchi static int BnxeRxPktsInitIdx(um_device_t * pUM,
738d14abf15SRobert Mustacchi                              int           idx)
739d14abf15SRobert Mustacchi {
740d14abf15SRobert Mustacchi     lm_device_t *   pLM = &pUM->lm_dev;
741d14abf15SRobert Mustacchi     lm_rx_chain_t * pLmRxChain;
742d14abf15SRobert Mustacchi     um_rxpacket_t * pRxPkt;
743d14abf15SRobert Mustacchi     lm_packet_t *   pLmPkt;
744d14abf15SRobert Mustacchi     u8_t *          pTmp;
745d14abf15SRobert Mustacchi     int postCnt, i;
746d14abf15SRobert Mustacchi 
747d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_RX(pUM, idx);
748d14abf15SRobert Mustacchi 
749d14abf15SRobert Mustacchi     pLmRxChain = &LM_RXQ(pLM, idx);
750d14abf15SRobert Mustacchi 
751d14abf15SRobert Mustacchi     s_list_clear(&pUM->rxq[idx].doneRxQ);
752d14abf15SRobert Mustacchi     pUM->rxq[idx].rxLowWater = pLM->params.l2_rx_desc_cnt[LM_CHAIN_IDX_CLI(pLM, idx)];
753d14abf15SRobert Mustacchi     pUM->rxq[idx].rxDiscards = 0;
754d14abf15SRobert Mustacchi     pUM->rxq[idx].rxCopied   = 0;
755d14abf15SRobert Mustacchi 
756d14abf15SRobert Mustacchi     s_list_clear(&pUM->rxq[idx].waitRxQ);
757d14abf15SRobert Mustacchi 
758d14abf15SRobert Mustacchi     /* allocate the packet descriptors */
759d14abf15SRobert Mustacchi     for (i = 0;
760d14abf15SRobert Mustacchi          i < pLM->params.l2_rx_desc_cnt[LM_CHAIN_IDX_CLI(pLM, idx)];
761d14abf15SRobert Mustacchi          i++)
762d14abf15SRobert Mustacchi     {
763d14abf15SRobert Mustacchi         if ((pTmp = kmem_zalloc(BnxeRxPktDescrSize(pUM),
764d14abf15SRobert Mustacchi                                 KM_NOSLEEP)) == NULL)
765d14abf15SRobert Mustacchi         {
766d14abf15SRobert Mustacchi             BnxeLogWarn(pUM, "Failed to alloc an rx packet descriptor!!!");
767d14abf15SRobert Mustacchi             break; /* continue without error */
768d14abf15SRobert Mustacchi         }
769d14abf15SRobert Mustacchi 
770d14abf15SRobert Mustacchi         pRxPkt            = (um_rxpacket_t *)(pTmp + SIZEOF_SIG);
771d14abf15SRobert Mustacchi         SIG(pRxPkt)       = L2PACKET_RX_SIG;
772d14abf15SRobert Mustacchi         pRxPkt->signature = pUM->rxBufSignature[LM_CHAIN_IDX_CLI(pLM, idx)];
773d14abf15SRobert Mustacchi 
774d14abf15SRobert Mustacchi         pLmPkt                     = (lm_packet_t *)pRxPkt;
775d14abf15SRobert Mustacchi         pLmPkt->u1.rx.hash_val_ptr = &pRxPkt->hash_value;
776d14abf15SRobert Mustacchi         pLmPkt->l2pkt_rx_info      = &pRxPkt->rx_info;
777d14abf15SRobert Mustacchi 
778d14abf15SRobert Mustacchi         if (BnxeRxBufAlloc(pUM, idx, pRxPkt) != 0)
779d14abf15SRobert Mustacchi         {
780d14abf15SRobert Mustacchi             BnxeRxPktDescrFree(pUM, pRxPkt);
781d14abf15SRobert Mustacchi             break; /* continue without error */
782d14abf15SRobert Mustacchi         }
783d14abf15SRobert Mustacchi 
784d14abf15SRobert Mustacchi         s_list_push_tail(&pLmRxChain->common.free_descq, &pLmPkt->link);
785d14abf15SRobert Mustacchi     }
786d14abf15SRobert Mustacchi 
787d14abf15SRobert Mustacchi     postCnt = s_list_entry_cnt(&pLmRxChain->common.free_descq);
788d14abf15SRobert Mustacchi 
789d14abf15SRobert Mustacchi     if (postCnt != pLM->params.l2_rx_desc_cnt[LM_CHAIN_IDX_CLI(pLM, idx)])
790d14abf15SRobert Mustacchi     {
791d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "%d rx buffers requested and only %d allocated!!!",
792d14abf15SRobert Mustacchi                     pLM->params.l2_rx_desc_cnt[LM_CHAIN_IDX_CLI(pLM, idx)],
793d14abf15SRobert Mustacchi                     postCnt);
794d14abf15SRobert Mustacchi     }
795d14abf15SRobert Mustacchi 
796d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_RX(pUM, idx);
797d14abf15SRobert Mustacchi 
798d14abf15SRobert Mustacchi     return 0;
799d14abf15SRobert Mustacchi }
800d14abf15SRobert Mustacchi 
801d14abf15SRobert Mustacchi 
BnxeRxPktsInit(um_device_t * pUM,int cliIdx)802d14abf15SRobert Mustacchi int BnxeRxPktsInit(um_device_t * pUM,
803d14abf15SRobert Mustacchi                    int           cliIdx)
804d14abf15SRobert Mustacchi {
805d14abf15SRobert Mustacchi     int idx;
806d14abf15SRobert Mustacchi 
807d14abf15SRobert Mustacchi     /* set the rx buffer signature for this plumb */
808d14abf15SRobert Mustacchi     atomic_swap_32(&pUM->rxBufSignature[cliIdx], (u32_t)ddi_get_time());
809d14abf15SRobert Mustacchi 
810d14abf15SRobert Mustacchi     switch (cliIdx)
811d14abf15SRobert Mustacchi     {
812d14abf15SRobert Mustacchi     case LM_CLI_IDX_FCOE:
813d14abf15SRobert Mustacchi 
814d14abf15SRobert Mustacchi         BnxeRxPktsInitIdx(pUM, FCOE_CID(&pUM->lm_dev));
815d14abf15SRobert Mustacchi         break;
816d14abf15SRobert Mustacchi 
817d14abf15SRobert Mustacchi     case LM_CLI_IDX_NDIS:
818d14abf15SRobert Mustacchi 
819d14abf15SRobert Mustacchi         LM_FOREACH_RSS_IDX(&pUM->lm_dev, idx)
820d14abf15SRobert Mustacchi         {
821d14abf15SRobert Mustacchi             BnxeRxPktsInitIdx(pUM, idx);
822d14abf15SRobert Mustacchi         }
823d14abf15SRobert Mustacchi 
824d14abf15SRobert Mustacchi         break;
825d14abf15SRobert Mustacchi 
826d14abf15SRobert Mustacchi     default:
827d14abf15SRobert Mustacchi 
828d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "ERROR: Invalid cliIdx for BnxeRxPktsInit (%d)", cliIdx);
829d14abf15SRobert Mustacchi         break;
830d14abf15SRobert Mustacchi     }
831d14abf15SRobert Mustacchi 
832d14abf15SRobert Mustacchi     return 0;
833d14abf15SRobert Mustacchi }
834d14abf15SRobert Mustacchi 
835d14abf15SRobert Mustacchi 
BnxeRxPktsFiniIdx(um_device_t * pUM,int idx)836d14abf15SRobert Mustacchi static void BnxeRxPktsFiniIdx(um_device_t * pUM,
837d14abf15SRobert Mustacchi                               int           idx)
838d14abf15SRobert Mustacchi {
839d14abf15SRobert Mustacchi     lm_rx_chain_t * pLmRxChain;
840d14abf15SRobert Mustacchi     um_rxpacket_t * pRxPkt;
841d14abf15SRobert Mustacchi     s_list_t        tmpList;
842d14abf15SRobert Mustacchi 
843d14abf15SRobert Mustacchi     pLmRxChain = &LM_RXQ(&pUM->lm_dev, idx);
844d14abf15SRobert Mustacchi 
845d14abf15SRobert Mustacchi     s_list_clear(&tmpList);
846d14abf15SRobert Mustacchi 
847d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_RX(pUM, idx);
848d14abf15SRobert Mustacchi     s_list_add_tail(&tmpList, &pLmRxChain->common.free_descq);
849d14abf15SRobert Mustacchi     s_list_clear(&pLmRxChain->common.free_descq);
850d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_RX(pUM, idx);
851d14abf15SRobert Mustacchi 
852d14abf15SRobert Mustacchi     BNXE_LOCK_ENTER_DONERX(pUM, idx);
853d14abf15SRobert Mustacchi     s_list_add_tail(&tmpList, &pUM->rxq[idx].doneRxQ);
854d14abf15SRobert Mustacchi     s_list_clear(&pUM->rxq[idx].doneRxQ);
855d14abf15SRobert Mustacchi     BNXE_LOCK_EXIT_DONERX(pUM, idx);
856d14abf15SRobert Mustacchi 
857d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&tmpList) !=
858d14abf15SRobert Mustacchi         pUM->lm_dev.params.l2_rx_desc_cnt[LM_CHAIN_IDX_CLI(&pUM->lm_dev, idx)])
859d14abf15SRobert Mustacchi     {
860d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "WARNING Missing RX packets (idx:%d) (%lu / %d - %u in stack)",
861d14abf15SRobert Mustacchi                     idx, s_list_entry_cnt(&tmpList),
862d14abf15SRobert Mustacchi                     pUM->lm_dev.params.l2_rx_desc_cnt[LM_CHAIN_IDX_CLI(&pUM->lm_dev, idx)],
863d14abf15SRobert Mustacchi                     pUM->rxq[idx].rxBufUpInStack);
864d14abf15SRobert Mustacchi     }
865d14abf15SRobert Mustacchi 
866d14abf15SRobert Mustacchi     /*
867d14abf15SRobert Mustacchi      * Back out all the packets in the "available for hardware use" queue.
868d14abf15SRobert Mustacchi      * Free the buffers associated with the descriptors as we go.
869d14abf15SRobert Mustacchi      */
870d14abf15SRobert Mustacchi     while (1)
871d14abf15SRobert Mustacchi     {
872d14abf15SRobert Mustacchi         pRxPkt = (um_rxpacket_t *)s_list_pop_head(&tmpList);
873d14abf15SRobert Mustacchi         if (pRxPkt == NULL)
874d14abf15SRobert Mustacchi         {
875d14abf15SRobert Mustacchi             break;
876d14abf15SRobert Mustacchi         }
877d14abf15SRobert Mustacchi 
878d14abf15SRobert Mustacchi         pRxPkt->lm_pkt.u1.rx.mem_phys[0].as_u64 = 0;
879d14abf15SRobert Mustacchi         pRxPkt->rx_info.mem_virt = NULL;
880d14abf15SRobert Mustacchi         pRxPkt->rx_info.mem_size = 0;
881d14abf15SRobert Mustacchi 
882d14abf15SRobert Mustacchi         ddi_dma_unbind_handle(pRxPkt->dmaHandle);
883d14abf15SRobert Mustacchi         ddi_dma_mem_free(&pRxPkt->dmaAccHandle);
884d14abf15SRobert Mustacchi         ddi_dma_free_handle(&pRxPkt->dmaHandle);
885d14abf15SRobert Mustacchi 
886d14abf15SRobert Mustacchi         BnxeRxPktDescrFree(pUM, pRxPkt);
887d14abf15SRobert Mustacchi     }
888d14abf15SRobert Mustacchi }
889d14abf15SRobert Mustacchi 
890d14abf15SRobert Mustacchi 
BnxeRxPktsFini(um_device_t * pUM,int cliIdx)891d14abf15SRobert Mustacchi void BnxeRxPktsFini(um_device_t * pUM,
892d14abf15SRobert Mustacchi                     int           cliIdx)
893d14abf15SRobert Mustacchi {
894d14abf15SRobert Mustacchi     int idx;
895d14abf15SRobert Mustacchi 
896d14abf15SRobert Mustacchi     /* reset the signature for this unplumb */
897d14abf15SRobert Mustacchi     atomic_swap_32(&pUM->rxBufSignature[cliIdx], 0);
898d14abf15SRobert Mustacchi 
899d14abf15SRobert Mustacchi     switch (cliIdx)
900d14abf15SRobert Mustacchi     {
901d14abf15SRobert Mustacchi     case LM_CLI_IDX_FCOE:
902d14abf15SRobert Mustacchi 
903d14abf15SRobert Mustacchi         BnxeRxPktsFiniIdx(pUM, FCOE_CID(&pUM->lm_dev));
904d14abf15SRobert Mustacchi         break;
905d14abf15SRobert Mustacchi 
906d14abf15SRobert Mustacchi     case LM_CLI_IDX_NDIS:
907d14abf15SRobert Mustacchi 
908d14abf15SRobert Mustacchi         LM_FOREACH_RSS_IDX(&pUM->lm_dev, idx)
909d14abf15SRobert Mustacchi         {
910d14abf15SRobert Mustacchi             BnxeRxPktsFiniIdx(pUM, idx);
911d14abf15SRobert Mustacchi         }
912d14abf15SRobert Mustacchi 
913d14abf15SRobert Mustacchi         break;
914d14abf15SRobert Mustacchi 
915d14abf15SRobert Mustacchi     default:
916d14abf15SRobert Mustacchi 
917d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "ERROR: Invalid cliIdx for BnxeRxPktsFini (%d)", cliIdx);
918d14abf15SRobert Mustacchi         break;
919d14abf15SRobert Mustacchi     }
920d14abf15SRobert Mustacchi }
921d14abf15SRobert Mustacchi 
922