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
BnxeRxPostBuffers(um_device_t * pUM,int idx,s_list_t * pReclaimList)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
BnxeRxPktDescrSize(um_device_t * pUM)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
BnxeRxPktDescrFree(um_device_t * pUM,um_rxpacket_t * pRxPkt)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
BnxeRxPktFree(char * free_arg)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
BnxeWaitForPacketsFromClient(um_device_t * pUM,int cliIdx)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 */
BnxeRxRingProcess(um_device_t * pUM,int idx,boolean_t polling,int numBytes)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 */
BnxeRxRingDump(um_device_t * pUM,int idx)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 */
BnxeRxPktsAbortIdx(um_device_t * pUM,int idx)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
BnxeRxPktsAbort(um_device_t * pUM,int cliIdx)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
BnxeRxBufAlloc(um_device_t * pUM,int idx,um_rxpacket_t * pRxPkt)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
BnxeRxPktsInitPostBuffersIdx(um_device_t * pUM,int idx)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
BnxeRxPktsInitPostBuffers(um_device_t * pUM,int cliIdx)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
BnxeRxPktsInitIdx(um_device_t * pUM,int idx)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
BnxeRxPktsInit(um_device_t * pUM,int cliIdx)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
BnxeRxPktsFiniIdx(um_device_t * pUM,int idx)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
BnxeRxPktsFini(um_device_t * pUM,int cliIdx)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