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