void SendOneQueuedPacket( PMRVDRV_ADAPTER Adapter ) { PNDIS_PACKET pPacket; NDIS_STATUS Status; USHORT usTxFrmSeqNum = 0, usTxFrmStatus = 0, usTCNSeqNum = 0; USHORT usTxCurrentRate = 0; PTXQ_KEEPER pTxQKeeper; PTXQ_NODE pTQNode; EnterCriticalSection(&Adapter->TxCriticalSection); if( Adapter->TxPacketCount ) { TxPacketDeQueue(Adapter, &pTxQKeeper, &pTQNode); Adapter->TxPacketCount--; pPacket = pTQNode -> pPacket; LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx if(pPacket) { Status = SendSinglePacket(Adapter,pPacket,&(pTQNode->DnldPacket)); EnterCriticalSection(&Adapter->TxCriticalSection); // tt tx if(Status == NDIS_STATUS_SUCCESS) { PushFreeTxQNode(Adapter->TxFreeQ,pTQNode); //Adapter->TxPacketCount--; //++dralee_20060327 } else { DBGPRINT(DBG_ERROR,(L"[TxDone] Send packet fail\r\n")); //Error handling , push back this node InsertTxQNodeFromHead(pTxQKeeper,pTQNode); //++dralee_20060327 Adapter->TxPacketCount++; } LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx } } else { LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx } }
/* ethernet device interface */ rt_err_t rt_wlan_dev_tx( rt_device_t dev, struct pbuf* packet) { struct rt_wlan_dev *wlandev=dev->user_data; WlanInfo *wlan = (WlanInfo*)wlandev->priv; WlanCard *card = wlan->card; rt_uint32_t level; if (packet == RT_NULL) return -RT_ERROR; SendSinglePacket(card, packet); level = rt_hw_interrupt_disable(); card->HisRegCpy &= ~HIS_TxDnLdRdy; rt_hw_interrupt_enable(level); return RT_EOK; }
/* ethernet device interface */ static rt_err_t mrvl_wlan_tx( rt_device_t dev, struct pbuf* packet) { WlanCard *card; rt_uint32_t level; RT_ASSERT(dev != RT_NULL); RT_ASSERT(packet != RT_NULL); card = WLAN_CARD(dev); SendSinglePacket(card, packet); level = rt_hw_interrupt_disable(); card->HisRegCpy &= ~HIS_TxDnLdRdy; rt_hw_interrupt_enable(level); return RT_EOK; }
NDIS_STATUS HandleTxSingleDoneEvent( PMRVDRV_ADAPTER Adapter ) { PNDIS_PACKET pPacket; NDIS_STATUS Status; USHORT usTxFrmSeqNum = 0, usTxFrmStatus = 0, usTCNSeqNum = 0; USHORT usTxCurrentRate = 0; PTXQ_KEEPER pTxQKeeper; PTXQ_NODE pTQNode; //DBGSTROBE_LINE_OFF(DBLINE2); DBGPRINT(DBG_TX | DBG_CRLF ,(L"+HandleTxSingleDoneEvent()\n")); Adapter->dwTxTimeoutCount = 0; /* Handle Txsingle done may be caused by txed data packet and command packet. If caused by command packet, Adapter->SentPacket == null. If caused by data packet, Adapter->SentPacket != null except the txed packet is null packet. When PPS is actived, null packet with last packet indication set may be sent to FW */ Status = NDIS_STATUS_SUCCESS; EnterCriticalSection(&Adapter->TxCriticalSection); pPacket = Adapter->SentPacket; Adapter->SentPacket = NULL; if ( ! wlan_ccx_isCurPacket(pPacket) ) { Adapter->TxPacketSendComplete++; //dralee_20051128 if ( Adapter->MediaConnectStatus == NdisMediaStateDisconnected ) { LeaveCriticalSection(&Adapter->TxCriticalSection); CleanUpSingleTxBuffer(Adapter); ResetRxPDQ(Adapter); return NDIS_STATUS_FAILURE; } DBGPRINT(DBG_TX|DBG_HELP,(L"[Marvell:HandleTxSingleDoneEvent] Adapter->TxPacketSendComplete=%d\n", Adapter->TxPacketSendComplete)); //dralee_20060629 if( Adapter->PPS_Enabled == 0 ) //WMM_UAPSD { if( Adapter->psState != PS_STATE_SLEEP ) { if( Adapter->TxPacketCount ) { TxPacketDeQueue(Adapter, &pTxQKeeper, &pTQNode); //++dralee_20060327 Adapter->TxPacketCount--; pPacket = pTQNode -> pPacket; LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx if(pPacket) { Status = SendSinglePacket(Adapter,pPacket,&(pTQNode->DnldPacket)); EnterCriticalSection(&Adapter->TxCriticalSection); // tt tx if(Status == NDIS_STATUS_SUCCESS) { PushFreeTxQNode(Adapter->TxFreeQ,pTQNode); //Adapter->TxPacketCount--; //++dralee_20060327 } else { DBGPRINT(DBG_ERROR,(L"[TxDone] Send packet fail\r\n")); //Error handling , push back this node InsertTxQNodeFromHead(pTxQKeeper,pTQNode); //++dralee_20060327 Adapter->TxPacketCount++; } LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx } else { DBGPRINT(DBG_ERROR,(L"severe error, Get NULL packet...\r\n")); // tt ++ wmm EnterCriticalSection(&Adapter->TxCriticalSection); // tt tx PushFreeTxQNode(Adapter->TxFreeQ,pTQNode); LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx // tt -- } } else if(Adapter->WmmDesc.WmmUapsdEnabled && Adapter->psState == PS_STATE_WAKEUP ) //PS mode enabled { LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx Adapter->bNullFrameSent = 1; SendNullPacket(Adapter, MRVDRV_WCB_POWER_MGMT_NULL_PACKET|MRVDRV_WCB_POWER_MGMT_LAST_PACKET); } // tt tx ++ else LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx // tt tx -- } else //080807 dralee LeaveCriticalSection(&Adapter->TxCriticalSection); } else //#else { //++dralee_20060327 if( Adapter->TxPacketCount && Adapter->psState != PS_STATE_SLEEP && Adapter->TxLock == 0 ) { TxPacketDeQueue(Adapter, &pTxQKeeper, &pTQNode); //++dralee_20060327 Adapter->TxPacketCount--; // tt ++ ps check // if ( pTQNode == NULL ) { ///crlo: queue is full. Leave now, instead of sending the packet // DBGPRINT(DBG_TX, ("pq: 3\n") ); // RETAILMSG(1,(L"Exit: %s, queue is full, LeaveCriticalSection \n", TEXT(__FUNCTION__))); // LeaveCriticalSection(&Adapter->TxCriticalSection); // return NDIS_STATUS_FAILURE; // } // tt -- pPacket = pTQNode -> pPacket; LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx if(pPacket) { Status = SendSinglePacket(Adapter,pPacket,&(pTQNode->DnldPacket)); EnterCriticalSection(&Adapter->TxCriticalSection); // tt tx if(Status == NDIS_STATUS_SUCCESS) { PushFreeTxQNode(Adapter->TxFreeQ,pTQNode); //Adapter->TxPacketCount--; //++dralee_20060327 } else { DBGPRINT(DBG_ERROR,(L"[TxDone] Send packet fail\r\n")); //Error handling , push back this node InsertTxQNodeFromHead(pTxQKeeper,pTQNode); //++dralee_20060327 Adapter->TxPacketCount++; } LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx } else { DBGPRINT(DBG_ERROR,(L"severe error, Get NULL packet...\r\n")); /* The original 37.p13 doesn't push the node back to the Tx queue. */ EnterCriticalSection(&Adapter->TxCriticalSection); // tt tx PushFreeTxQNode(Adapter->TxFreeQ,pTQNode); LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx } } else if( Adapter->psState == PS_STATE_WAKEUP && (CheckLastPacketIndication(Adapter)) ) { if(Adapter->TxLock == 0) { SendNullPacket(Adapter, (MRVDRV_WCB_POWER_MGMT_NULL_PACKET|MRVDRV_WCB_POWER_MGMT_LAST_PACKET)); Adapter->TxLock = 1; } LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx } // tt tx ++ else LeaveCriticalSection(&Adapter->TxCriticalSection); // tt tx // tt tx -- } //#endif // WMM_UAPSD } else { LeaveCriticalSection(&Adapter->TxCriticalSection); //080807 +dralee DBGPRINT(DBG_CCX, (L"[HandleTxSingleDone] It is CCX packet\n")); ///crlo:slowping ++ wlan_ccx_clrCurPacket(); ///crlo:slowping -- } //this condiction only true when ps_confirm is enqueue, but not txed. //It's possible when doing GetCmdFromQueueToExecute(), Adapter->SentPacket != 0 //that will stop downloading this command if ( Adapter->psState == PS_STATE_SLEEP && Adapter->bPSConfirm==FALSE ) { if( IsThisHostPowerState(Adapter, HTWK_STATE_FULL_POWER) || IsThisHostPowerState(Adapter, HTWK_STATE_SLEEP) ) { if (Adapter->CurCmd == NULL) { GetCmdFromQueueToExecute (Adapter); } } } //dralee_20060607, As command sending flow may be disrupted due to Adapter->SentPacket != null //we add this condition to let flow started again. else if ( Adapter->CurCmd == NULL && Adapter->SentPacket == NULL && Adapter->psState != PS_STATE_SLEEP ) { GetCmdFromQueueToExecute (Adapter); } return NDIS_STATUS_SUCCESS; }