📄 wlan_tx.c
字号:
/*
* File : wlan_tx.c
*/
#include "include.h"
static u8 tx_temp_buf[MRVDRV_ETH_TX_PACKET_BUFFER_SIZE];
int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
{
wlan_adapter *Adapter = priv->adapter;
int ret = WLAN_STATUS_SUCCESS;
TxPD LocalTxPD;
TxPD *pLocalTxPD = &LocalTxPD;
u8 *ptr = tx_temp_buf;
ENTER();
if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
PRINTK("Tx Error: Bad skb length %d : %d\n", skb->len,
MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
ret = WLAN_STATUS_FAILURE;
goto done;
}
TXRX_DEBUG_GET_TIME(1);
memset(pLocalTxPD, 0, sizeof(TxPD));
pLocalTxPD->TxPacketLength = skb->len;
#ifdef WMM
if(Adapter->wmm.enabled) {
/*
* original skb->priority has been overwritten
* by wmm_map_and_add_skb()
*/
pLocalTxPD->Priority = (u8)skb->priority;
#ifdef WMM_UAPSD
if (Adapter->PSState != PS_STATE_FULL_POWER)
{
if ((Adapter->CurBssParams.wmm_uapsd_enabled == TRUE) && (Adapter->wmm.qosinfo != 0))
{
if (wmm_lists_empty(priv) && (Adapter->sleep_period.period != 0))
{
Adapter->wmm.no_more_packet = 1;
pLocalTxPD->PowerMgmt = MRVDRV_TxPD_POWER_MGMT_LAST_PACKET;
}
}
}
#endif
}
#endif /* WMM */
/* offset of actaul data */
pLocalTxPD->TxPacketLocation = sizeof(TxPD);
/* TxCtrl set by user or default */
pLocalTxPD->TxControl = Adapter->PktTxCtrl;
#ifdef BIG_ENDIAN
endian_convert_pLocalTxPD(pLocalTxPD);
#endif
memcpy(pLocalTxPD->TxDestAddrHigh, skb->data, MRVDRV_ETH_ADDR_LEN);
HEXDUMP("TxPD", (u8 *) pLocalTxPD, sizeof(TxPD));
memcpy(ptr, pLocalTxPD, sizeof(TxPD));
ptr += sizeof(TxPD);
HEXDUMP("Tx Data", (u8 *) skb->data, skb->len);
memcpy(ptr, skb->data, skb->len);
ret = sbi_host_to_card(priv, MVMS_DAT,
tx_temp_buf, skb->len + sizeof(TxPD));
TXRX_DEBUG_GET_TIME(2);
if (ret) {
PRINTK("Tx Error: sbi_host_to_card failed: 0x%X\n",ret);
goto done;
}
PRINTK1("SendSinglePacket succeeds\n");
done:
if (!ret) {
priv->stats.tx_packets++;
priv->stats.tx_bytes += skb->len;
}
else {
priv->stats.tx_dropped++;
priv->stats.tx_errors++;
}
/* need to be freed in all cases */
os_free_tx_packet(priv);
LEAVE();
return ret;
}
void wlan_process_tx(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
u32 flags;
OS_INTERRUPT_SAVE_AREA;
ENTER();
spin_lock_irqsave(&Adapter->CurrentTxLock, flags);
if (!Adapter->CurrentTxSkb) {
spin_unlock_irqrestore(&Adapter->CurrentTxLock, flags);
PRINTK("wlan_process_tx(): Adapter->CurrentTxSkb is NULL!\n");
goto done;
}
spin_unlock_irqrestore(&Adapter->CurrentTxLock, flags);
if (Adapter->SurpriseRemoved == TRUE) {
PRINTK("wlan_process_tx(): Device Removed!\n");
goto done;
}
if (Adapter->MediaConnectStatus == WlanMediaStateDisconnected) {
PRINTK("wlan_process_tx(): WlanMediaStateDisconnected!\n");
if (Adapter->CurrentTxSkb) {
kfree_skb(Adapter->CurrentTxSkb);
Adapter->CurrentTxSkb = NULL;
priv->stats.tx_dropped++;
priv->stats.tx_errors++;
}
goto done;
}
if(priv->wlan_dev.dnld_sent) {
PRINTK("wlan_process_tx(): dnld_sent = %d, not sending\n",
priv->wlan_dev.dnld_sent);
goto done;
}
#ifdef PS_REQUIRED
if ((Adapter->PSState == PS_STATE_SLEEP)
#ifdef PS_PRESLEEP
|| (Adapter->PSState == PS_STATE_PRE_SLEEP)
#endif
) {
PRINTK1("In PS State %d"
" - Not sending the packet\n", Adapter->PSState);
goto done;
}
#endif
SendSinglePacket(priv, Adapter->CurrentTxSkb);
OS_INT_DISABLE;
priv->adapter->HisRegCpy &= ~HIS_TxDnLdRdy;
OS_INT_RESTORE;
done:
LEAVE();
}
int wlan_tx_packet(wlan_private * priv, struct sk_buff *skb)
{
u32 flags;
wlan_adapter *Adapter = priv->adapter;
int ret = WLAN_STATUS_SUCCESS;
ENTER();
spin_lock_irqsave(&Adapter->CurrentTxLock, flags);
#ifdef WMM
if(Adapter->wmm.enabled) {
wmm_map_and_add_skb(priv, skb);
wake_up_interruptible(&priv->MainThread.waitQ);
} else
#endif /* WMM */
if (!Adapter->CurrentTxSkb) {
Adapter->CurrentTxSkb = skb;
wake_up_interruptible(&priv->MainThread.waitQ);
} else {
ret = WLAN_STATUS_FAILURE;
}
spin_unlock_irqrestore(&Adapter->CurrentTxLock, flags);
LEAVE();
return ret;
}
#ifdef WMM_UAPSD
int SendNullPacket(wlan_private * priv, u8 pwr_mgmt)
{
wlan_adapter *Adapter = priv->adapter;
TxPD txpd;
int ret = WLAN_STATUS_SUCCESS;
ENTER();
if (priv->adapter->SurpriseRemoved == TRUE) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
if (priv->adapter->MediaConnectStatus == WlanMediaStateDisconnected) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
memset(&txpd, 0, sizeof(TxPD));
txpd.TxControl = Adapter->PktTxCtrl;
txpd.PowerMgmt = pwr_mgmt;
txpd.TxPacketLocation = sizeof(TxPD);
#ifdef BIG_ENDIAN
endian_convert_pLocalTxPD(&txpd);
#endif
memcpy(tx_temp_buf, &txpd, sizeof(TxPD));
ret = sbi_host_to_card(priv, MVMS_DAT,
tx_temp_buf, sizeof(TxPD));
if (ret != 0)
{
PRINTK("SendNullPacket failed!\n");
goto done;
}
done:
LEAVE();
return ret;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -