/************************************************************************ * Function - CheckAndSendPacketFromIndex() * * Description - This function dequeues the data/control packet from the * specified queue for transmission. * * Parameters - Adapter : Pointer to the driver control structure. * - iQIndex : The queue Identifier. * * Returns - None. * ****************************************************************************/ static VOID CheckAndSendPacketFromIndex(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF) { struct sk_buff *QueuePacket = NULL; char *pControlPacket = NULL; INT Status = 0; int iPacketLen = 0; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%zd ====>", (psSF-Adapter->PackInfo)); if ((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount)) { /* Get data packet */ if (!psSF->ucDirection) return; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount "); if (Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) return; /* in idle mode */ /* Check for Free Descriptors */ if (atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " No Free Tx Descriptor(%d) is available for Data pkt..", atomic_read(&Adapter->CurrNumFreeTxDesc)); return; } spin_lock_bh(&psSF->SFQueueLock); QueuePacket = psSF->FirstTxQueue; if (QueuePacket) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet"); if (psSF->bEthCSSupport) iPacketLen = QueuePacket->len; else iPacketLen = QueuePacket->len-ETH_HLEN; iPacketLen <<= 3; if (iPacketLen <= GetSFTokenCount(Adapter, psSF)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d", (iPacketLen >> 3)); DEQUEUEPACKET(psSF->FirstTxQueue, psSF->LastTxQueue); psSF->uiCurrentBytesOnHost -= (QueuePacket->len); psSF->uiCurrentPacketsOnHost--; atomic_dec(&Adapter->TotalPacketCount); spin_unlock_bh(&psSF->SFQueueLock); Status = SendPacketFromQueue(Adapter, psSF, QueuePacket); psSF->uiPendedLast = FALSE; } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n", psSF->uiCurrentTokenCount, iPacketLen); /* this part indicates that because of non-availability of the tokens pkt has not been send out hence setting the pending flag indicating the host to send it out first next iteration. */ psSF->uiPendedLast = TRUE; spin_unlock_bh(&psSF->SFQueueLock); } } else {
/** * @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 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 {
INT flushAllAppQ(void) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); PPER_TARANG_DATA pTarang = NULL; struct sk_buff *PacketToDrop = NULL; for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) { while (pTarang->RxAppControlHead != NULL) { PacketToDrop = pTarang->RxAppControlHead; DEQUEUEPACKET(pTarang->RxAppControlHead, pTarang->RxAppControlTail); dev_kfree_skb(PacketToDrop); } pTarang->AppCtrlQueueLen = 0; memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0, sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES)); } return STATUS_SUCCESS; }
INT flushAllAppQ(void) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); struct bcm_tarang_data *pTarang = NULL; struct sk_buff *PacketToDrop = NULL; for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) { while (pTarang->RxAppControlHead != NULL) { PacketToDrop = pTarang->RxAppControlHead; DEQUEUEPACKET(pTarang->RxAppControlHead, pTarang->RxAppControlTail); dev_kfree_skb(PacketToDrop); } pTarang->AppCtrlQueueLen = 0; /* dropped contrl packet statistics also should be reset. */ memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0, sizeof(struct bcm_mibs_dropped_cntrl_msg)); } return STATUS_SUCCESS; }
static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF) { struct sk_buff *QueuePacket=NULL; char *pControlPacket = NULL; INT Status=0; int iPacketLen=0; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%zd ====>", (psSF-Adapter->PackInfo)); if((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount)) { if(!psSF->ucDirection ) return; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount "); if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) return; if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " No Free Tx Descriptor(%d) is available for Data pkt..",atomic_read(&Adapter->CurrNumFreeTxDesc)); return ; } spin_lock_bh(&psSF->SFQueueLock); QueuePacket=psSF->FirstTxQueue; if(QueuePacket) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet"); if(psSF->bEthCSSupport) iPacketLen = QueuePacket->len; else iPacketLen = QueuePacket->len-ETH_HLEN; iPacketLen<<=3; if(iPacketLen <= GetSFTokenCount(Adapter, psSF)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d", (iPacketLen >> 3)); DEQUEUEPACKET(psSF->FirstTxQueue,psSF->LastTxQueue); psSF->uiCurrentBytesOnHost -= (QueuePacket->len); psSF->uiCurrentPacketsOnHost--; atomic_dec(&Adapter->TotalPacketCount); spin_unlock_bh(&psSF->SFQueueLock); Status = SendPacketFromQueue(Adapter, psSF, QueuePacket); psSF->uiPendedLast = FALSE; } else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n", psSF->uiCurrentTokenCount, iPacketLen); psSF->uiPendedLast = TRUE; spin_unlock_bh(&psSF->SFQueueLock); } }