/** * @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; }
int InterfaceResume (struct usb_interface *intf) { PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); printk("=================================\n"); mdelay(100); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) intf->pm_usage_cnt =1 ; #endif psIntfAdapter->bSuspended = FALSE; StartInterruptUrb(psIntfAdapter); InterfaceRx(psIntfAdapter); return 0; }
static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) { INT value = 0; UINT status = STATUS_SUCCESS; status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter); if(status != STATUS_SUCCESS) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "InitCardAndDownloadFirmware failed.\n"); return status; } if(TRUE == psIntfAdapter->psAdapter->fw_download_done) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Sending first interrupt URB down......"); if(StartInterruptUrb(psIntfAdapter)) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB"); } //now register the cntrl interface. //after downloading the f/w waiting for 5 sec to get the mailbox interrupt. psIntfAdapter->psAdapter->waiting_to_fw_download_done = FALSE; value = wait_event_timeout(psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue, psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ); if(value == 0) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Mailbox Interrupt has not reached to Driver.."); } else { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Got the mailbox interrupt ...Registering control interface...\n "); } if(register_control_device_interface(psIntfAdapter->psAdapter) < 0) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Register Control Device failed..."); return -EIO; } } return 0; }
/*this is transmit call-back(BULK OUT)*/ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { struct bcm_usb_tcb *pTcb = (struct bcm_usb_tcb *)urb->context; struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter; struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter; bool bpowerDownMsg = false; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if (unlikely(netif_msg_tx_done(Adapter))) pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status); if (urb->status != STATUS_SUCCESS) { if (urb->status == -EPIPE) { psIntfAdapter->psAdapter->bEndPointHalted = TRUE; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx URB has got cancelled. status :%d", urb->status); } } pTcb->bUsed = false; atomic_dec(&psIntfAdapter->uNumTcbUsed); if (TRUE == psAdapter->bPreparingForLowPowerMode) { if (((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) { bpowerDownMsg = TRUE; /* This covers the bus err while Idle Request msg sent down. */ if (urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Request msg failed to reach to Modem"); /* Signalling the cntrl pkt path in Ioctl */ wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } if (psAdapter->bDoSuspend == false) { psAdapter->IdleMode = TRUE; /* since going in Idle mode completed hence making this var false */ psAdapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); /* Signalling the cntrl pkt path in Ioctl*/ wake_up(&psAdapter->lowpower_mode_wait_queue); } } else if ((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && (pControlMsg->szData[0] == LINK_UP_ACK) && (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) { /* This covers the bus err while shutdown Request msg sent down. */ if (urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Shutdown Request Msg failed to reach to Modem"); /* Signalling the cntrl pkt path in Ioctl */ wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } bpowerDownMsg = TRUE; if (psAdapter->bDoSuspend == false) { psAdapter->bShutStatus = TRUE; /* since going in shutdown mode completed hence making this var false */ psAdapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in shutdown Mode State..."); /* Signalling the cntrl pkt path in Ioctl */ wake_up(&psAdapter->lowpower_mode_wait_queue); } } if (psAdapter->bDoSuspend && bpowerDownMsg) { /* issuing bus suspend request */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Issuing the Bus suspend request to USB stack"); psIntfAdapter->bPreparingForBusSuspend = TRUE; schedule_work(&psIntfAdapter->usbSuspendWork); } } err_exit: usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); }
/*this is transmit call-back(BULK OUT)*/ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { PUSB_TCB pTcb= (PUSB_TCB)urb->context; PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter; CONTROL_MESSAGE *pControlMsg = (CONTROL_MESSAGE *)urb->transfer_buffer; PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ; BOOLEAN bpowerDownMsg = FALSE ; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); #if 0 struct timeval tv; UINT time_ms = 0; #endif if(urb->status != STATUS_SUCCESS) { if(urb->status == -EPIPE) { psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status); } } pTcb->bUsed = FALSE; atomic_dec(&psIntfAdapter->uNumTcbUsed); if(TRUE == psAdapter->bPreparingForLowPowerMode) { #if 0 do_gettimeofday(&tv); time_ms = tv.tv_sec *1000 + tv.tv_usec/1000; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms); #endif if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) { bpowerDownMsg = TRUE ; //This covers the bus err while Idle Request msg sent down. if(urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem"); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } if(psAdapter->bDoSuspend == FALSE) { psAdapter->IdleMode = TRUE; //since going in Idle mode completed hence making this var false; psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); } } else if((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && (pControlMsg->szData[0] == LINK_UP_ACK) && (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) { //This covers the bus err while shutdown Request msg sent down. if(urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem"); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } bpowerDownMsg = TRUE ; if(psAdapter->bDoSuspend == FALSE) { psAdapter->bShutStatus = TRUE; //since going in shutdown mode completed hence making this var false; psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State..."); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); } } if(psAdapter->bDoSuspend && bpowerDownMsg) { //issuing bus suspend request BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Issuing the Bus suspend request to USB stack"); psIntfAdapter->bPreparingForBusSuspend = TRUE; schedule_work(&psIntfAdapter->usbSuspendWork); } } err_exit : #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) usb_buffer_free(urb->dev, urb->transfer_buffer_length, #else usb_free_coherent(urb->dev, urb->transfer_buffer_length, #endif urb->transfer_buffer, urb->transfer_dma); }
void shiftDetect(PMINI_ADAPTER Adapter) { ULONG CurrentTime = 0; ULONG ulResetPattern[] = {HANDSHAKE_PATTERN1,HANDSHAKE_PATTERN2}; UINT uiRegRead = 0; int status = 0; static ULONG uiHandShakeTime = 0; if( TRUE == Adapter->fw_download_done && FALSE == Adapter->bShutStatus && FALSE == Adapter->IdleMode && FALSE == Adapter->device_removed) { //Need to read the one register to produce issue.... status = rdmaltWithLock(Adapter,DUMMY_REG, &uiRegRead, sizeof(uiRegRead)); if(status < 0) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); } else { status = rdmaltWithLock(Adapter,CHIP_ID_REG, &uiRegRead, sizeof(uiRegRead)); if(status < 0) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); } else { if(Adapter->chip_id != uiRegRead) { CurrentTime = jiffies*1000/HZ; /* Something wrong, not able to read chip id, lets try to reset and recover. if does not recover after reset, try reset in TIME_TO_RESET intervals. */ if((CurrentTime - uiHandShakeTime) >= TIME_TO_RESET) { UINT uiRetries = 0; // Hold the RDMWRM Mutex so that RDM/WRM cannot happen while reset. /* To ensure that InterruptOut doesn't get called when device is in Idle mode... */ down(&Adapter->rdmwrmsync); Adapter->StopAllXaction = TRUE; Bcm_kill_all_URBs(Adapter->pvInterfaceAdapter); // As we are reseting the UDMA, existing mailbox counters wont be valid. // So mark the existing counters as used. // atomic_set(&Adapter->CurrNumFreeTxDesc, 0); ((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bUDMAResetDone = FALSE; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Resetting UDMA: Sending the pattern to INT OUT\n"); /* Send InterruptOut pattern to reset */ InterruptOut(Adapter,(PUCHAR)&ulResetPattern[0]); Adapter->StopAllXaction = FALSE; if(StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB"); } while(FALSE == (((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bUDMAResetDone)) { uiRetries++; if(uiRetries >= UDMA_RST_HNDSHK_RETRY_CNT) { // // Handshake failed...perhaps older firmware. // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Resetting UDMA: Handshake failed...perhaps old fw\n"); break; } msleep(10); } uiHandShakeTime = CurrentTime; up(&Adapter->rdmwrmsync); } } } } } }
static void prepare_low_power_mode(struct urb *urb, struct bcm_interface_adapter *interface, struct bcm_mini_adapter *ps_adapter, struct bcm_mini_adapter *ad, struct bcm_link_request *p_control_msg, bool *b_power_down_msg) { if (((p_control_msg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && (p_control_msg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) { *b_power_down_msg = TRUE; /* * This covers the bus err while Idle Request msg * sent down. */ if (urb->status != STATUS_SUCCESS) { ps_adapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Request msg failed to reach to Modem"); /* Signalling the cntrl pkt path in Ioctl */ wake_up(&ps_adapter->lowpower_mode_wait_queue); StartInterruptUrb(interface); return; } if (ps_adapter->bDoSuspend == false) { ps_adapter->IdleMode = TRUE; /* since going in Idle mode completed hence making this var false */ ps_adapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); /* Signalling the cntrl pkt path in Ioctl*/ wake_up(&ps_adapter->lowpower_mode_wait_queue); } } else if ((p_control_msg->Leader.Status == LINK_UP_CONTROL_REQ) && (p_control_msg->szData[0] == LINK_UP_ACK) && (p_control_msg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && (p_control_msg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) { /* * This covers the bus err while shutdown Request * msg sent down. */ if (urb->status != STATUS_SUCCESS) { ps_adapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Shutdown Request Msg failed to reach to Modem"); /* Signalling the cntrl pkt path in Ioctl */ wake_up(&ps_adapter->lowpower_mode_wait_queue); StartInterruptUrb(interface); return; } *b_power_down_msg = TRUE; if (ps_adapter->bDoSuspend == false) { ps_adapter->bShutStatus = TRUE; /* * since going in shutdown mode completed hence * making this var false */ ps_adapter->bPreparingForLowPowerMode = false; BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in shutdown Mode State..."); /* Signalling the cntrl pkt path in Ioctl */ wake_up(&ps_adapter->lowpower_mode_wait_queue); } } if (ps_adapter->bDoSuspend && *b_power_down_msg) { /* issuing bus suspend request */ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Issuing the Bus suspend request to USB stack"); interface->bPreparingForBusSuspend = TRUE; schedule_work(&interface->usbSuspendWork); } }
/** @ingroup tx_functions Transmit thread */ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ ) { #ifndef BCM_SHM_INTERFACE int status = 0; #endif UINT calltransmit = 1; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Entring to wait for signal from the interrupt service thread!Adapter = 0x%lx",(ULONG) Adapter); while(1) { if(Adapter->LinkUpStatus){ wait_event_timeout(Adapter->tx_packet_wait_queue, ((atomic_read(&Adapter->TxPktAvail) && (MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc)) && (Adapter->device_removed == FALSE))) || (1 == Adapter->uiFirstInterrupt) || kthread_should_stop() #ifndef BCM_SHM_INTERFACE || (TRUE == Adapter->bEndPointHalted) #endif , msecs_to_jiffies(10)); } else{ wait_event(Adapter->tx_packet_wait_queue, ((atomic_read(&Adapter->TxPktAvail) && (MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc)) && (Adapter->device_removed == FALSE))) || (1 == Adapter->uiFirstInterrupt) || kthread_should_stop() #ifndef BCM_SHM_INTERFACE || (TRUE == Adapter->bEndPointHalted) #endif ); } if(kthread_should_stop() || Adapter->device_removed) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n"); Adapter->transmit_packet_thread = NULL; return 0; } if(Adapter->uiFirstInterrupt == 1) { SetUpTargetDsxBuffers(Adapter); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Seting DSX...\n"); Adapter->uiFirstInterrupt +=1; #ifndef BCM_SHM_INTERFACE status = download_ddr_settings(Adapter); if(status) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "DDR DOWNLOAD FAILED!\n"); #endif continue; } #ifndef BCM_SHM_INTERFACE //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); } } #endif 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); } #ifdef BCM_SHM_INTERFACE spin_lock_bh(&Adapter->txtransmitlock); if(Adapter->txtransmit_running == 0) { Adapter->txtransmit_running = 1; calltransmit = 1; } else calltransmit = 0; spin_unlock_bh(&Adapter->txtransmitlock); #endif if(calltransmit) transmit_packets(Adapter); atomic_set(&Adapter->TxPktAvail, 0); } return 0; }