static void usbbcm_disconnect (struct usb_interface *intf) { PS_INTERFACE_ADAPTER psIntfAdapter = NULL; PMINI_ADAPTER psAdapter = NULL; struct usb_device *udev = NULL; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usb disconnected"); if(intf == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf pointer is NULL"); return; } psIntfAdapter = usb_get_intfdata(intf); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter); if(psIntfAdapter == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapter pointer is NULL"); return; } psAdapter = psIntfAdapter->psAdapter; if(psAdapter->bDoSuspend) intf->needs_remote_wakeup = 0; psAdapter->device_removed = TRUE ; usb_set_intfdata(intf, NULL); InterfaceAdapterFree(psIntfAdapter); udev = interface_to_usbdev (intf); usb_put_dev(udev); usb_deregister_dev (intf, &usbbcm_class); }
int bcmsdio_set_blk_size(int func, unsigned int blk_size) { struct sdio_func *function = func_data[BCM_SDIO_FN1]->func; int ret = 0; if (function == NULL) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ***Error: %s %d ***\n", __func__, __LINE__); return -ENON_INTF_ERR; } sdio_claim_host(function); if(func != BCM_SDIO_FN0) ret = sdio_set_block_size(function, blk_size); else { BCM_SDIO_FN0_BLK_SIZE = blk_size; sdio_f0_writeb(function,BCM_SDIO_FN0_BLK_SIZE & 0xFF, 0x10, &ret); if(ret < 0) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "failed to set the f0 block size"); } sdio_f0_writeb(function,(BCM_SDIO_FN0_BLK_SIZE >> 8) &0xFF , 0x11, &ret); if(ret < 0) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "failed to set the f0 block size"); } } sdio_release_host(function); return ret; }
VOID putUsbSuspend(struct work_struct *work) { PS_INTERFACE_ADAPTER psIntfAdapter = NULL ; struct usb_interface *intf = NULL ; psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER,usbSuspendWork); intf=psIntfAdapter->interface ; if(psIntfAdapter->bSuspended == FALSE) { usb_autopm_put_interface(intf); if(intf->is_active == 0) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Interface Suspend Completely\n"); } else { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Interface suspend failed.."); } } else { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Interface Resumed Completely\n"); } }
static __inline int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) { int i = 0; for(i = 0; i < MAXIMUM_USB_TCB; i++) { if((psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Tx urb for index %d", i); return -ENOMEM; } } for(i = 0; i < MAXIMUM_USB_RCB; i++) { if ((psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx urb for index %d", i); return -ENOMEM; } if((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx buffer for index %d", i); return -ENOMEM; } psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = MAX_DATA_BUFFER_SIZE; } return 0; }
static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, IN S_CLASSIFIER_ENTRY *pstClassifierEntry, S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule, B_UINT8 u8AssociatedPHSI) { S_PHS_RULE *pstAddPhsRule = NULL; UINT nPhsRuleIndex = 0; BOOLEAN bPHSRuleOrphaned = FALSE; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); psPhsRule->u8RefCnt =0; /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/ bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable, pstClassifierEntry->pstPhsRule); //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI, eActiveClassifierRuleContext, &pstAddPhsRule); if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier"); if(psPhsRule->u8PHSI == 0) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n"); return ERR_PHS_INVALID_PHS_RULE; } //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId if(FALSE == bPHSRuleOrphaned) { pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL); if(NULL == pstClassifierEntry->pstPhsRule) { return ERR_PHSRULE_MEMALLOC_FAIL; } } memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE)); } else { //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule"); if(bPHSRuleOrphaned) { kfree(pstClassifierEntry->pstPhsRule); pstClassifierEntry->pstPhsRule = NULL; } pstClassifierEntry->pstPhsRule = pstAddPhsRule; } pstClassifierEntry->bUsed = TRUE; pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI; pstClassifierEntry->uiClassifierRuleId = uiClsId; pstClassifierEntry->pstPhsRule->u8RefCnt++; pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule; return PHS_SUCCESS; }
static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) { UINT len = u32FirmwareLength; INT retval = STATUS_SUCCESS; PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); int bytes; if (NULL == readbackbuff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED"); return -ENOMEM; } while (u32FirmwareLength && !retval) { len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len); if (bytes < 0) { retval = bytes; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d", retval); break; } retval = bcm_compare_buff_contents(readbackbuff, mappedbuffer, len); if (STATUS_SUCCESS != retval) break; u32StartingAddress += len; u32FirmwareLength -= len; mappedbuffer += len; } /* end of while (u32FirmwareLength && !retval) */ kfree(readbackbuff); return retval; }
int InterruptOut(PMINI_ADAPTER Adapter, PUCHAR pData) { int status = STATUS_SUCCESS; int lenwritten = 0; PS_INTERFACE_ADAPTER psInterfaceAdapter = Adapter->pvInterfaceAdapter; if( FALSE == Adapter->bShutStatus && FALSE == Adapter->IdleMode && FALSE == Adapter->bPreparingForLowPowerMode && FALSE == Adapter->device_removed) { status = usb_interrupt_msg (psInterfaceAdapter->udev, usb_sndintpipe(psInterfaceAdapter->udev, psInterfaceAdapter->sIntrOut.int_out_endpointAddr), pData, 8, &lenwritten, 5000); } if(status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Sending clear pattern down fails with status:%d..\n",status); return status; } else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "NOB Sent down :%d", lenwritten); return STATUS_SUCCESS; } } /* InterruptOut() */
/** @ingroup tx_functions This function despatches packet from the specified queue. @return Zero(success) or Negative value(failure) */ static INT SendPacketFromQueue(struct bcm_mini_adapter *Adapter,/**<Logical Adapter*/ struct bcm_packet_info *psSF, /**<Queue identifier*/ struct sk_buff *Packet) /**<Pointer to the packet to be sent*/ { INT Status = STATUS_FAILURE; UINT uiIndex = 0, PktLen = 0; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "=====>"); if (!Adapter || !Packet || !psSF) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "Got NULL Adapter or Packet"); return -EINVAL; } if (psSF->liDrainCalculated == 0) psSF->liDrainCalculated = jiffies; /* send the packet to the fifo.. */ PktLen = Packet->len; Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value); if (Status == 0) { for (uiIndex = 0; uiIndex < MIBS_MAX_HIST_ENTRIES; uiIndex++) { if ((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) Adapter->aTxPktSizeHist[uiIndex]++; } } BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "<====="); return Status; }
int InterfaceSuspend (struct usb_interface *intf, pm_message_t message) { PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=================================\n"); //Bcm_kill_all_URBs(psIntfAdapter); psIntfAdapter->bSuspended = TRUE; if(TRUE == psIntfAdapter->bPreparingForBusSuspend) { psIntfAdapter->bPreparingForBusSuspend = FALSE; if(psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) { psIntfAdapter->psAdapter->IdleMode = TRUE ; BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Idle Mode.."); } else { psIntfAdapter->psAdapter->bShutStatus = TRUE; BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Shutdown Mode.."); } } psIntfAdapter->psAdapter->bPreparingForLowPowerMode = FALSE; //Signaling the control pkt path wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue); return 0; }
static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char *buff,unsigned int len) { int retval = STATUS_SUCCESS; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); if((len-sizeof(unsigned int))<4) { if(memcmp(readbackbuff , buff, len)) { retval=-EINVAL; } } else { len-=4; while(len) { if(*(unsigned int*)&readbackbuff[len] != *(unsigned int *)&buff[len]) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper"); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&readbackbuff[len]); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); retval=-EINVAL; break; } len-=4; } } return retval; }
static ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>"); if(NULL == Adapter || (psSF < Adapter->PackInfo && (uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd\n", Adapter, (psSF-Adapter->PackInfo)); return 0; } if(FALSE != psSF->bValid && psSF->ucDirection) { if(0 != psSF->uiCurrentTokenCount) { return psSF->uiCurrentTokenCount; } else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %zd Available %u\n", psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); psSF->uiPendedLast = 1; } } else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %zd not valid\n", psSF-Adapter->PackInfo); } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <==="); return 0; }
void InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter) { unsigned int uiRegVal = 0; INT Status = 0; int bytes; if (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { /* clear idlemode interrupt. */ uiRegVal = 0; Status = wrmalt(Adapter, DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegVal, sizeof(uiRegVal)); if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Failed with err :%d", Status); return; } } else { /* clear Interrupt EP registers. */ bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegVal, sizeof(uiRegVal)); if (bytes < 0) { Status = bytes; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM of DEVICE_INT_OUT_EP_REG0 failed with Err :%d", Status); return; } bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegVal, sizeof(uiRegVal)); if (bytes < 0) { Status = bytes; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM of DEVICE_INT_OUT_EP_REG1 failed with Err :%d", Status); return; } } }
static INT SendPacketFromQueue(PMINI_ADAPTER Adapter, PacketInfo *psSF, struct sk_buff* Packet) { INT Status=STATUS_FAILURE; UINT uiIndex =0,PktLen = 0; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "=====>"); if(!Adapter || !Packet || !psSF) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "Got NULL Adapter or Packet"); return -EINVAL; } if(psSF->liDrainCalculated==0) { psSF->liDrainCalculated = jiffies; } PktLen = Packet->len; Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value); if(Status == 0) { for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++) { if((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) Adapter->aTxPktSizeHist[uiIndex]++; } } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "<====="); return Status; }
int bcmsdio_reg_driver(bcmwimax_probe probe_fn, bcmwimax_remove remove_fn, bcmwimax_platform_init platform_init_fn,bcmwimax_platform_deinit platform_deinit_fn, int irq_num) { int ret = 0; if (probe_notifier || remove_notifier ||platform_deinit_notifier) { BCM_DEBUG_PRINT(debuglevel, KERN_ERR " Notifiers are already registered\n"); ret = -EINVAL; goto end; } if (!probe_fn || !remove_fn || !platform_deinit_fn) { BCM_DEBUG_PRINT(debuglevel, KERN_ERR " Can not register NULL notifier\n"); ret = -EINVAL; goto end; } probe_notifier = probe_fn; remove_notifier = remove_fn; platform_deinit_notifier = platform_deinit_fn; g_irq_num = irq_num; bcmsdio_mmc_host = NULL; bcmsdio_suspend_hldr = NULL; bcmsdio_resume_hldr = NULL; ret = sdio_register_driver(&bcmsdio_driver); if(!ret) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT " Calling platform init function\n"); ret = platform_init_fn(); if(ret) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "Platform Init returned error and hence unregestering\n"); bcmsdio_unreg_driver(); } } else { probe_notifier = NULL; remove_notifier = NULL; platform_deinit_notifier = NULL; } if(g_irq_num >= 0) { ret = platform_device_register(&p_wimax_device); if(ret) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "Platform Device Register returned error: %x\n", ret); goto end; } ret = platform_driver_register(&wimax_device); } end: return ret; }
int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, S_PHS_RULE *decomp_phs_rules,UINT *header_size) { int phss,size=0; S_PHS_RULE *tmp_memb; int bit,i=0; unsigned char *phsf,*phsm; int in_buf_len = *header_size-1; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); in_buf++; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"====>\n"); *header_size = 0; if((decomp_phs_rules == NULL )) return 0; tmp_memb = decomp_phs_rules; //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi)); //*header_size = tmp_memb->u8PHSFLength; phss = tmp_memb->u8PHSS; phsf = tmp_memb->u8PHSF; phsm = tmp_memb->u8PHSM; if(phss > MAX_PHS_LENGTHS) phss = MAX_PHS_LENGTHS; //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index)); while((phss > 0) && (size < in_buf_len)) { bit = ((*phsm << i)& SUPPRESS); if(bit == SUPPRESS) { *out_buf = *phsf; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d", phss,*phsf,*out_buf); } else { *out_buf = *in_buf; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d", phss,*in_buf,*out_buf); in_buf++; size++; } out_buf++; phsf++; phss--; i++; *header_size=*header_size + 1; if(i > MAX_NO_BIT) { i=0; phsm++; } } return size; }
/** * @ingroup tx_functions * Transmit thread */ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/) { int status = 0; while (!kthread_should_stop()) { /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */ if (Adapter->LinkUpStatus) wait_event_timeout(Adapter->tx_packet_wait_queue, tx_pending(Adapter), msecs_to_jiffies(10)); else wait_event_interruptible(Adapter->tx_packet_wait_queue, tx_pending(Adapter)); if (Adapter->device_removed) break; if (Adapter->downloadDDR == 1) { Adapter->downloadDDR += 1; status = download_ddr_settings(Adapter); if (status) pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status); continue; } /* Check end point for halt/stall. */ if (Adapter->bEndPointHalted == TRUE) { Bcm_clear_halt_of_endpoints(Adapter); Adapter->bEndPointHalted = FALSE; StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); } if (Adapter->LinkUpStatus && !Adapter->IdleMode) { if (atomic_read(&Adapter->TotalPacketCount)) update_per_sf_desc_cnts(Adapter); } if (atomic_read(&Adapter->CurrNumFreeTxDesc) && Adapter->LinkStatus == SYNC_UP_REQUEST && !Adapter->bSyncUpRequestSent) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage"); LinkMessage(Adapter); } if ((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up"); Adapter->usIdleModePattern = ABORT_IDLE_MODE; Adapter->bWakeUpDevice = TRUE; wake_up(&Adapter->process_rx_cntrlpkt); } transmit_packets(Adapter); atomic_set(&Adapter->TxPktAvail, 0); } BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n"); Adapter->transmit_packet_thread = NULL; return 0; }
static BOOLEAN MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule, IPV6Header *pstIpv6Header) { UINT uiLoopIndex = 0; UINT uiIpv6AddIndex = 0; UINT uiIpv6AddrNoLongWords = 4; ULONG aulDestIP[4]; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); /* * This is the no. of Destination Addresses * ie Range of IP Addresses contained in the classifier rule * for which we need to match */ UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength; if (uiCountIPDestinationAddresses == 0) return TRUE; /* First Convert the Ip Address in the packet to Host Endian order */ for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) aulDestIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]); for (uiLoopIndex = 0; uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Received Packet :\n "); DumpIpv6Address(aulDestIP); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex]); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]); for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { if ((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex]) != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { /* * Match failed for current Ipv6 Address. * Try next Ipv6 Address */ break; } if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { /* Match Found */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n"); return TRUE; } } } return FALSE; }
/** * @ingroup ctrl_pkt_functions * Thread to handle control pkt reception */ int control_packet_handler(struct bcm_mini_adapter *Adapter /* pointer to adapter object*/) { struct sk_buff *ctrl_packet = NULL; unsigned long flags = 0; /* struct timeval tv; */ /* int *puiBuffer = NULL; */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Entering to make thread wait on control packet event!"); while (1) { wait_event_interruptible(Adapter->process_rx_cntrlpkt, atomic_read(&Adapter->cntrlpktCnt) || Adapter->bWakeUpDevice || kthread_should_stop()); if (kthread_should_stop()) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Exiting\n"); return 0; } if (TRUE == Adapter->bWakeUpDevice) { Adapter->bWakeUpDevice = FALSE; if ((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && ((TRUE == Adapter->IdleMode) || (TRUE == Adapter->bShutStatus))) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Calling InterfaceAbortIdlemode\n"); /* * Adapter->bTriedToWakeUpFromlowPowerMode * = TRUE; */ InterfaceIdleModeWakeup(Adapter); } continue; } while (atomic_read(&Adapter->cntrlpktCnt)) { spin_lock_irqsave(&Adapter->control_queue_lock, flags); ctrl_packet = Adapter->RxControlHead; if (ctrl_packet) { DEQUEUEPACKET(Adapter->RxControlHead, Adapter->RxControlTail); /* Adapter->RxControlHead=ctrl_packet->next; */ } spin_unlock_irqrestore(&Adapter->control_queue_lock, flags); handle_rx_control_packet(Adapter, ctrl_packet); atomic_dec(&Adapter->cntrlpktCnt); } SetUpTargetDsxBuffers(Adapter); } return STATUS_SUCCESS; }
static __inline int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len) { struct urb *urb = pTcb->urb; int retval = 0; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) urb->transfer_buffer = usb_buffer_alloc(psIntfAdapter->udev, len, #else urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len, #endif GFP_ATOMIC, &urb->transfer_dma); if (!urb->transfer_buffer) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n"); return -ENOMEM; } memcpy(urb->transfer_buffer, data, len); urb->transfer_buffer_length = len; BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n"); //For T3B,INT OUT end point will be used as bulk out end point if((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE)) { usb_fill_int_urb(urb, psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe, urb->transfer_buffer, len, write_bulk_callback, pTcb, psIntfAdapter->sBulkOut.int_out_interval); } else { usb_fill_bulk_urb(urb, psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe, urb->transfer_buffer, len, write_bulk_callback, pTcb); } urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */ if(FALSE == psIntfAdapter->psAdapter->device_removed && FALSE == psIntfAdapter->psAdapter->bEndPointHalted && FALSE == psIntfAdapter->bSuspended && FALSE == psIntfAdapter->bPreparingForBusSuspend) { retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval); if(retval == -EPIPE) { psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } } } return retval; }
static VOID DumpIpv6Header(IPV6Header *pstIpv6Header) { UCHAR ucVersion; UCHAR ucPrio; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---"); ucVersion = pstIpv6Header->ucVersionPrio & 0xf0; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x\n", ucVersion); ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x\n", ucPrio); /* * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, * "Flow Label : %x\n",(pstIpv6Header->ucVersionPrio &0xf0); */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x\n", ntohs(pstIpv6Header->usPayloadLength)); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x\n", pstIpv6Header->ucNextHeader); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x\n", pstIpv6Header->ucHopLimit); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Src Address :\n"); DumpIpv6Address(pstIpv6Header->ulSrcIpAddress); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Dest Address :\n"); DumpIpv6Address(pstIpv6Header->ulDestIpAddress); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header End---"); }
int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) { int retval = STATUS_SUCCESS; PUCHAR buff = NULL; /* Config File is needed for the Driver to download the Config file and Firmware. Check for the Config file to be first to be sent from the Application */ atomic_set (&Adapter->uiMBupdate, FALSE); if(!Adapter->bCfgDownloaded && psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) { /*Can't Download Firmware.*/ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Download the config File first\n"); return -EINVAL; } /* If Config File, Finish the DDR Settings and then Download CFG File */ if(psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) { retval = bcm_download_config_file (Adapter, psFwInfo); } else { buff = kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL); if(buff==NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory"); return -ENOMEM; } retval = copy_from_user(buff,psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); if(retval != STATUS_SUCCESS) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed"); retval = -EFAULT; goto error ; } retval = buffDnldVerify(Adapter, buff, psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress); if(retval != STATUS_SUCCESS) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"f/w download failed status :%d", retval); goto error; } } error: kfree(buff); return retval; }
static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, unsigned char *phsf,unsigned char *phsm,unsigned int phss, unsigned int phsv,UINT* new_header_size) { unsigned int size=0; int bit,i=0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm); if(phss>(*new_header_size)) { phss=*new_header_size; } while(phss > 0) { bit = ((*phsm << i)& SUPPRESS); if(bit == SUPPRESS) { if(*in_buffer != *phsf) { if(phsv == VERIFY) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",phss,*in_buffer,*phsf); return STATUS_PHS_NOCOMPRESSION; } } else BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success for field %d buf %d phsf %d",phss,*in_buffer,*phsf); } else { *out_buffer = *in_buffer; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer); out_buffer++; size++; } in_buffer++; phsf++; phss--; i++; if(i > MAX_NO_BIT) { i=0; phsm++; } } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success"); *new_header_size = size; return STATUS_PHS_COMPRESSED; }
static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) { UINT uiLoopIndex=0; UINT uiIpv6AddIndex=0; UINT uiIpv6AddrNoLongWords = 4; ULONG aulSrcIP[4]; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); /* //This is the no. of Src Addresses ie Range of IP Addresses contained //in the classifier rule for which we need to match */ UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength; if(0 == uiCountIPSrcAddresses) return TRUE; //First Convert the Ip Address in the packet to Host Endian order for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) { aulSrcIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]); } for(uiLoopIndex=0;uiLoopIndex<uiCountIPSrcAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords) { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Received Packet : \n "); DumpIpv6Address(aulSrcIP); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Mask In Classifier Rule: \n"); DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex]); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Classifier Rule : \n"); DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]); for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) { if((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex]) != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { //Match failed for current Ipv6 Address.Try next Ipv6 Address break; } if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { //Match Found BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n"); return TRUE; } } } return FALSE; }
static void print_usb_interface_desc(struct usb_interface_descriptor *usb_intf_desc) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** INTERFACE DESCRIPTOR *********************"); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength: %x", usb_intf_desc->bLength); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType: %x", usb_intf_desc->bDescriptorType); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceNumber: %x", usb_intf_desc->bInterfaceNumber); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bAlternateSetting: %x", usb_intf_desc->bAlternateSetting); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bNumEndpoints: %x", usb_intf_desc->bNumEndpoints); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceClass: %x", usb_intf_desc->bInterfaceClass); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceSubClass: %x", usb_intf_desc->bInterfaceSubClass); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceProtocol: %x", usb_intf_desc->bInterfaceProtocol); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "iInterface :%x\n",usb_intf_desc->iInterface); }
int InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter) { ULONG Status = 0; if (Adapter->bTriedToWakeUpFromlowPowerMode) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Wake up already attempted.. ignoring\n"); } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing Low Power Mode Abort pattern to the Device\n"); Adapter->bTriedToWakeUpFromlowPowerMode = TRUE; InterfaceAbortIdlemode(Adapter, Adapter->usIdleModePattern); } return Status; }
int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc) { /* unsigned int reg = 0; */ mm_segment_t oldfs = {0}; int errno = 0, len = 0; /* ,is_config_file = 0 */ loff_t pos = 0; PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; /* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */ char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); if (!buff) return -ENOMEM; while (1) { oldfs = get_fs(); set_fs(get_ds()); len = vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos); set_fs(oldfs); if (len <= 0) { if (len < 0) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0"); errno = len; } else { errno = 0; BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!"); } break; } /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, * DBG_LVL_ALL, buff, * MAX_TRANSFER_CTRL_BYTE_USB); */ errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len); if (errno) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "WRM Failed! status: %d", errno); break; } on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; } kfree(buff); return errno; }
int bcmsdio_cmd52(unsigned int data, unsigned addr, unsigned rw, unsigned func,int *perrval) { struct sdio_func *function = func_data[BCM_SDIO_FN1]->func; int ret = data; int count = 0; *perrval = 0; if (function == NULL) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ** NULL FUNC PTR: x%x\n", func); return -ENON_INTF_ERR; } sdio_claim_host(function); if(func_data[BCM_SDIO_FN1]->bremoved) { ret = -ENON_INTF_ERR; BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT "Error: bremoved is non zero :%d", func_data[BCM_SDIO_FN1]->bremoved); goto rel_host; } while ( count < SDIO_CMD_RETRIES ) { if (rw) { if(func != BCM_SDIO_FN0) sdio_writeb(function, data, addr,perrval); else sdio_f0_writeb(function, data, addr,perrval); } else { if(func != 0 ) ret = sdio_readb(function, addr,perrval); else ret = sdio_f0_readb(function,addr,perrval); } if(!(*perrval)) break; count++; } if(count) BCM_DEBUG_PRINT(debuglevel, "Count is higher than 0 for cmd52: %x\n", count); if(*perrval) { BCM_DEBUG_PRINT(debuglevel, "ERR IN CMD52 %d rw: %x addr: %x, count: %x\n", *perrval, rw, addr, count); } rel_host: sdio_release_host(function); return ret; }
static void get_data_packet(struct bcm_mini_adapter *ad, struct bcm_packet_info *ps_sf) { int packet_len; struct sk_buff *qpacket; if (!ps_sf->ucDirection) return; BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount "); if (ad->IdleMode || ad->bPreparingForLowPowerMode) return; /* in idle mode */ /* Check for Free Descriptors */ if (atomic_read(&ad->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS) { BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " No Free Tx Descriptor(%d) is available for Data pkt..", atomic_read(&ad->CurrNumFreeTxDesc)); return; } spin_lock_bh(&ps_sf->SFQueueLock); qpacket = ps_sf->FirstTxQueue; if (qpacket) { BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet"); if (ps_sf->bEthCSSupport) packet_len = qpacket->len; else packet_len = qpacket->len - ETH_HLEN; packet_len <<= 3; if (packet_len <= GetSFTokenCount(ad, ps_sf)) { BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d", (packet_len >> 3)); DEQUEUEPACKET(ps_sf->FirstTxQueue, ps_sf->LastTxQueue); ps_sf->uiCurrentBytesOnHost -= (qpacket->len); ps_sf->uiCurrentPacketsOnHost--; atomic_dec(&ad->TotalPacketCount); spin_unlock_bh(&ps_sf->SFQueueLock); SendPacketFromQueue(ad, ps_sf, qpacket); ps_sf->uiPendedLast = false; } else {
/*++ PhsUpdateClassifierRule Routine Description: Exported function to add or modify a PHS Rule. Arguments: IN void* pvContext - PHS Driver Specific Context IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table. Return Value: 0 if successful, >0 Error. --*/ ULONG PhsUpdateClassifierRule(IN void* pvContext, IN B_UINT16 uiVcid , IN B_UINT16 uiClsId , IN S_PHS_RULE *psPhsRule, IN B_UINT8 u8AssociatedPHSI) { ULONG lStatus =0; UINT nSFIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n"); if(pDeviceExtension == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n"); return ERR_PHS_INVALID_DEVICE_EXETENSION; } if(u8AssociatedPHSI == 0) { return ERR_PHS_INVALID_PHS_RULE; } /* Retrieve the SFID Entry Index for requested Service Flow */ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid,&pstServiceFlowEntry); if(nSFIndex == PHS_INVALID_TABLE_INDEX) { /* This is a new SF. Create a mapping entry for this */ lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId, pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI); return lStatus; } /* SF already Exists Add PHS Rule to existing SF */ lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId, pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI); return lStatus; }
ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI) { ULONG lStatus =0; UINT nSFIndex =0, nClsidIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n"); if(pDeviceExtension) { //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry); if(nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); return ERR_SF_MATCH_FAIL; } pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable; if(pstClassifierRulesTable) { for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++) { if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) { if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) { if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule); memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY)); } } } } } return lStatus; }