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