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