diff options
Diffstat (limited to '')
-rw-r--r-- | drivers/staging/vt6656/rxtx.c | 2408 |
1 files changed, 718 insertions, 1690 deletions
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 704f4d3639be..2d1ef88808ff 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -25,22 +25,12 @@ * Date: May 20, 2003 * * Functions: - * s_vGenerateTxParameter - Generate tx dma required parameter. - * s_vGenerateMACHeader - Translate 802.3 to 802.11 header - * csBeacon_xmit - beacon tx function - * csMgmt_xmit - management tx function - * s_uGetDataDuration - get tx data required duration - * s_uFillDataHead- fulfill tx data duration header - * s_uGetRTSCTSDuration- get rtx/cts required duration - * s_uGetRTSCTSRsvTime- get rts/cts reserved time - * s_uGetTxRsvTime- get frame reserved time - * s_vFillCTSHead- fulfill CTS ctl header - * s_vFillFragParameter- Set fragment ctl parameter. - * s_vFillRTSHead- fulfill RTS ctl header - * s_vFillTxKey- fulfill tx encrypt key - * s_vSWencryption- Software encrypt header - * vDMA0_tx_80211- tx 802.11 frame via dma0 - * vGenerateFIFOHeader- Generate tx FIFO ctl header + * vnt_generate_tx_parameter - Generate tx dma required parameter. + * vnt_get_duration_le - get tx data required duration + * vnt_get_rtscts_duration_le- get rtx/cts required duration + * vnt_get_rtscts_rsvtime_le- get rts/cts reserved time + * vnt_get_rsvtime- get frame reserved time + * vnt_fill_cts_head- fulfill CTS ctl header * * Revision History: * @@ -48,33 +38,25 @@ #include "device.h" #include "rxtx.h" -#include "tether.h" #include "card.h" -#include "bssdb.h" #include "mac.h" -#include "michael.h" -#include "tkip.h" -#include "wctl.h" #include "rf.h" -#include "datarate.h" #include "usbpipe.h" -#include "iocmd.h" -static int msglevel = MSG_LEVEL_INFO; +static const u16 vnt_time_stampoff[2][MAX_RATE] = { + {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23},/* Long Preamble */ + {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23},/* Short Preamble */ +}; -static const u16 wTimeStampOff[2][MAX_RATE] = { - {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble - {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble - }; +static const u16 vnt_fb_opt0[2][5] = { + {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */ + {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */ +}; -static const u16 wFB_Opt0[2][5] = { - {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0 - {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1 - }; -static const u16 wFB_Opt1[2][5] = { - {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0 - {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1 - }; +static const u16 vnt_fb_opt1[2][5] = { + {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */ + {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */ +}; #define RTSDUR_BB 0 #define RTSDUR_BA 1 @@ -91,268 +73,59 @@ static const u16 wFB_Opt1[2][5] = { #define DATADUR_A_F0 12 #define DATADUR_A_F1 13 -static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum, - u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl); - -static struct vnt_usb_send_context *s_vGetFreeContext(struct vnt_private *); - -static u16 s_vGenerateTxParameter(struct vnt_private *pDevice, - u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer, - struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize, - int bNeedACK, struct ethhdr *psEthHeader, bool need_rts); - -static void s_vGenerateMACHeader(struct vnt_private *pDevice, - u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader, - int bNeedEncrypt, u16 wFragType, u32 uFragIdx); - -static void s_vFillTxKey(struct vnt_private *pDevice, - struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead, - PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen, - struct vnt_mic_hdr *mic_hdr); - -static void s_vSWencryption(struct vnt_private *pDevice, - PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize); - -static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType, - u32 cbFrameLength, u16 wRate, int bNeedAck); - -static __le16 s_uGetRTSCTSRsvTime(struct vnt_private *priv, - u8 rsv_type, u8 pkt_type, u32 frame_length, u16 current_rate); - -static u16 s_vFillCTSHead(struct vnt_private *pDevice, - u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength, - int bNeedAck, u16 wCurrentRate, u8 byFBOption); - -static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, - union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck, - struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption); - -static __le16 s_uGetDataDuration(struct vnt_private *pDevice, - u8 byPktType, int bNeedAck); - -static __le16 s_uGetRTSCTSDuration(struct vnt_private *pDevice, - u8 byDurType, u32 cbFrameLength, u8 byPktType, u16 wRate, - int bNeedAck, u8 byFBOption); - static struct vnt_usb_send_context - *s_vGetFreeContext(struct vnt_private *priv) + *vnt_get_free_context(struct vnt_private *priv) { struct vnt_usb_send_context *context = NULL; int ii; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n"); + dev_dbg(&priv->usb->dev, "%s\n", __func__); - for (ii = 0; ii < priv->cbTD; ii++) { - if (!priv->apTD[ii]) + for (ii = 0; ii < priv->num_tx_context; ii++) { + if (!priv->tx_context[ii]) return NULL; - context = priv->apTD[ii]; + context = priv->tx_context[ii]; if (context->in_use == false) { context->in_use = true; memset(context->data, 0, MAX_TOTAL_SIZE_WITH_ALL_HEADERS); + + context->hdr = NULL; + return context; } } - if (ii == priv->cbTD) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n"); + if (ii == priv->num_tx_context) + dev_dbg(&priv->usb->dev, "%s No Free Tx Context\n", __func__); return NULL; } -static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum, - u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl) -{ - struct net_device_stats *stats = &pDevice->stats; - struct vnt_tx_pkt_info *pkt_info = pDevice->pkt_info; - - pkt_info[byPktNum].fifo_ctl = wFIFOCtl; - memcpy(pkt_info[byPktNum].dest_addr, pbyDestAddr, ETH_ALEN); - - stats->tx_bytes += wPktLength; -} - -static void s_vFillTxKey(struct vnt_private *pDevice, - struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead, - PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen, - struct vnt_mic_hdr *mic_hdr) -{ - u8 *pbyBuf = (u8 *)&fifo_head->adwTxKey[0]; - __le32 *pdwIV = (__le32 *)pbyIVHead; - __le32 *pdwExtIV = (__le32 *)((u8 *)pbyIVHead + 4); - struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf; - __le32 rev_iv_counter; - - /* Fill TXKEY */ - if (pTransmitKey == NULL) - return; - - rev_iv_counter = cpu_to_le32(pDevice->dwIVCounter); - *pdwIV = cpu_to_le32(pDevice->dwIVCounter); - pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf; - - switch (pTransmitKey->byCipherSuite) { - case KEY_CTL_WEP: - if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) { - memcpy(pDevice->abyPRNG, (u8 *)&rev_iv_counter, 3); - memcpy(pDevice->abyPRNG + 3, pTransmitKey->abyKey, - pTransmitKey->uKeyLength); - } else { - memcpy(pbyBuf, (u8 *)&rev_iv_counter, 3); - memcpy(pbyBuf + 3, pTransmitKey->abyKey, - pTransmitKey->uKeyLength); - if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) { - memcpy(pbyBuf+8, (u8 *)&rev_iv_counter, 3); - memcpy(pbyBuf+11, pTransmitKey->abyKey, - pTransmitKey->uKeyLength); - } - - memcpy(pDevice->abyPRNG, pbyBuf, 16); - } - /* Append IV after Mac Header */ - *pdwIV &= cpu_to_le32(WEP_IV_MASK); - *pdwIV |= cpu_to_le32((u32)pDevice->byKeyIndex << 30); - - pDevice->dwIVCounter++; - if (pDevice->dwIVCounter > WEP_IV_MASK) - pDevice->dwIVCounter = 0; - - break; - case KEY_CTL_TKIP: - pTransmitKey->wTSC15_0++; - if (pTransmitKey->wTSC15_0 == 0) - pTransmitKey->dwTSC47_16++; - - TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, - pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, - pDevice->abyPRNG); - memcpy(pbyBuf, pDevice->abyPRNG, 16); - - /* Make IV */ - memcpy(pdwIV, pDevice->abyPRNG, 3); - - *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & - 0xc0) | 0x20); - /* Append IV&ExtIV after Mac Header */ - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "vFillTxKey()---- pdwExtIV: %x\n", *pdwExtIV); - - break; - case KEY_CTL_CCMP: - pTransmitKey->wTSC15_0++; - if (pTransmitKey->wTSC15_0 == 0) - pTransmitKey->dwTSC47_16++; - - memcpy(pbyBuf, pTransmitKey->abyKey, 16); - - /* Make IV */ - *pdwIV = 0; - *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & - 0xc0) | 0x20); - - *pdwIV |= cpu_to_le32((u32)(pTransmitKey->wTSC15_0)); - - /* Append IV&ExtIV after Mac Header */ - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - - if (!mic_hdr) - return; - - /* MICHDR0 */ - mic_hdr->id = 0x59; - mic_hdr->payload_len = cpu_to_be16(wPayloadLen); - memcpy(mic_hdr->mic_addr2, pMACHeader->addr2, ETH_ALEN); - - mic_hdr->tsc_47_16 = cpu_to_be32(pTransmitKey->dwTSC47_16); - mic_hdr->tsc_15_0 = cpu_to_be16(pTransmitKey->wTSC15_0); - - /* MICHDR1 */ - if (ieee80211_has_a4(pMACHeader->frame_control)) - mic_hdr->hlen = cpu_to_be16(28); - else - mic_hdr->hlen = cpu_to_be16(22); - - memcpy(mic_hdr->addr1, pMACHeader->addr1, ETH_ALEN); - memcpy(mic_hdr->addr2, pMACHeader->addr2, ETH_ALEN); - - /* MICHDR2 */ - memcpy(mic_hdr->addr3, pMACHeader->addr3, ETH_ALEN); - mic_hdr->frame_control = cpu_to_le16( - le16_to_cpu(pMACHeader->frame_control) & 0xc78f); - mic_hdr->seq_ctrl = cpu_to_le16( - le16_to_cpu(pMACHeader->seq_ctrl) & 0xf); - - if (ieee80211_has_a4(pMACHeader->frame_control)) - memcpy(mic_hdr->addr4, pMACHeader->addr4, ETH_ALEN); - } -} - -static void s_vSWencryption(struct vnt_private *pDevice, - PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize) -{ - u32 cbICVlen = 4; - u32 dwICV = 0xffffffff; - u32 *pdwICV; - - if (pTransmitKey == NULL) - return; - - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - //======================================================================= - // Append ICV after payload - dwICV = ether_crc_le(wPayloadSize, pbyPayloadHead); - pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize); - // finally, we must invert dwCRC to get the correct answer - *pdwICV = cpu_to_le32(~dwICV); - // RC4 encryption - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); - //======================================================================= - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - //======================================================================= - //Append ICV after payload - dwICV = ether_crc_le(wPayloadSize, pbyPayloadHead); - pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize); - // finally, we must invert dwCRC to get the correct answer - *pdwICV = cpu_to_le32(~dwICV); - // RC4 encryption - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); - //======================================================================= - } -} - static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) { - return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2] + return cpu_to_le16(vnt_time_stampoff[priv->preamble_type % 2] [rate % MAX_RATE]); } -/*byPktType : PK_TYPE_11A 0 - PK_TYPE_11B 1 - PK_TYPE_11GB 2 - PK_TYPE_11GA 3 -*/ -static u32 s_uGetTxRsvTime(struct vnt_private *priv, u8 pkt_type, +static u32 vnt_get_rsvtime(struct vnt_private *priv, u8 pkt_type, u32 frame_length, u16 rate, int need_ack) { u32 data_time, ack_time; - data_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, + data_time = vnt_get_frame_time(priv->preamble_type, pkt_type, frame_length, rate); if (pkt_type == PK_TYPE_11B) - ack_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, 14, - (u16)priv->byTopCCKBasicRate); + ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, + 14, (u16)priv->top_cck_basic_rate); else - ack_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, 14, - (u16)priv->byTopOFDMBasicRate); + ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, + 14, (u16)priv->top_ofdm_basic_rate); if (need_ack) - return data_time + priv->uSIFS + ack_time; + return data_time + priv->sifs + ack_time; return data_time; } @@ -360,1715 +133,970 @@ static u32 s_uGetTxRsvTime(struct vnt_private *priv, u8 pkt_type, static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type, u32 frame_length, u16 rate, int need_ack) { - return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type, + return cpu_to_le16((u16)vnt_get_rsvtime(priv, pkt_type, frame_length, rate, need_ack)); } -//byFreqType: 0=>5GHZ 1=>2.4GHZ -static __le16 s_uGetRTSCTSRsvTime(struct vnt_private *priv, +static __le16 vnt_get_rtscts_rsvtime_le(struct vnt_private *priv, u8 rsv_type, u8 pkt_type, u32 frame_length, u16 current_rate) { u32 rrv_time, rts_time, cts_time, ack_time, data_time; rrv_time = rts_time = cts_time = ack_time = data_time = 0; - data_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, + data_time = vnt_get_frame_time(priv->preamble_type, pkt_type, frame_length, current_rate); if (rsv_type == 0) { - rts_time = BBuGetFrameTime(priv->byPreambleType, - pkt_type, 20, priv->byTopCCKBasicRate); - cts_time = ack_time = BBuGetFrameTime(priv->byPreambleType, - pkt_type, 14, priv->byTopCCKBasicRate); + rts_time = vnt_get_frame_time(priv->preamble_type, + pkt_type, 20, priv->top_cck_basic_rate); + cts_time = ack_time = vnt_get_frame_time(priv->preamble_type, + pkt_type, 14, priv->top_cck_basic_rate); } else if (rsv_type == 1) { - rts_time = BBuGetFrameTime(priv->byPreambleType, - pkt_type, 20, priv->byTopCCKBasicRate); - cts_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, - 14, priv->byTopCCKBasicRate); - ack_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, - 14, priv->byTopOFDMBasicRate); + rts_time = vnt_get_frame_time(priv->preamble_type, + pkt_type, 20, priv->top_cck_basic_rate); + cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, + 14, priv->top_cck_basic_rate); + ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, + 14, priv->top_ofdm_basic_rate); } else if (rsv_type == 2) { - rts_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, - 20, priv->byTopOFDMBasicRate); - cts_time = ack_time = BBuGetFrameTime(priv->byPreambleType, - pkt_type, 14, priv->byTopOFDMBasicRate); + rts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, + 20, priv->top_ofdm_basic_rate); + cts_time = ack_time = vnt_get_frame_time(priv->preamble_type, + pkt_type, 14, priv->top_ofdm_basic_rate); } else if (rsv_type == 3) { - cts_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, - 14, priv->byTopCCKBasicRate); - ack_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, - 14, priv->byTopOFDMBasicRate); + cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, + 14, priv->top_cck_basic_rate); + ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, + 14, priv->top_ofdm_basic_rate); - rrv_time = cts_time + ack_time + data_time + 2 * priv->uSIFS; + rrv_time = cts_time + ack_time + data_time + 2 * priv->sifs; return cpu_to_le16((u16)rrv_time); } - rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS; + rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->sifs; return cpu_to_le16((u16)rrv_time); } -//byFreqType 0: 5GHz, 1:2.4Ghz -static __le16 s_uGetDataDuration(struct vnt_private *pDevice, - u8 byPktType, int bNeedAck) +static __le16 vnt_get_duration_le(struct vnt_private *priv, + u8 pkt_type, int need_ack) { - u32 uAckTime = 0; + u32 ack_time = 0; - if (bNeedAck) { - if (byPktType == PK_TYPE_11B) - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, - byPktType, 14, pDevice->byTopCCKBasicRate); + if (need_ack) { + if (pkt_type == PK_TYPE_11B) + ack_time = vnt_get_frame_time(priv->preamble_type, + pkt_type, 14, priv->top_cck_basic_rate); else - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, - byPktType, 14, pDevice->byTopOFDMBasicRate); - return cpu_to_le16((u16)(pDevice->uSIFS + uAckTime)); + ack_time = vnt_get_frame_time(priv->preamble_type, + pkt_type, 14, priv->top_ofdm_basic_rate); + + return cpu_to_le16((u16)(priv->sifs + ack_time)); } return 0; } -//byFreqType: 0=>5GHZ 1=>2.4GHZ -static __le16 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType, - u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck, - u8 byFBOption) +static __le16 vnt_get_rtscts_duration_le(struct vnt_usb_send_context *context, + u8 dur_type, u8 pkt_type, u16 rate) { - u32 uCTSTime = 0, uDurTime = 0; + struct vnt_private *priv = context->priv; + u32 cts_time = 0, dur_time = 0; + u32 frame_length = context->frame_len; + u8 need_ack = context->need_ack; - switch (byDurType) { + switch (dur_type) { case RTSDUR_BB: case RTSDUR_BA: case RTSDUR_BA_F0: case RTSDUR_BA_F1: - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, - 14, pDevice->byTopCCKBasicRate); - uDurTime = uCTSTime + 2 * pDevice->uSIFS + - s_uGetTxRsvTime(pDevice, byPktType, - cbFrameLength, wRate, bNeedAck); + cts_time = vnt_get_frame_time(priv->preamble_type, + pkt_type, 14, priv->top_cck_basic_rate); + dur_time = cts_time + 2 * priv->sifs + + vnt_get_rsvtime(priv, pkt_type, + frame_length, rate, need_ack); break; case RTSDUR_AA: case RTSDUR_AA_F0: case RTSDUR_AA_F1: - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, - 14, pDevice->byTopOFDMBasicRate); - uDurTime = uCTSTime + 2 * pDevice->uSIFS + - s_uGetTxRsvTime(pDevice, byPktType, - cbFrameLength, wRate, bNeedAck); + cts_time = vnt_get_frame_time(priv->preamble_type, + pkt_type, 14, priv->top_ofdm_basic_rate); + dur_time = cts_time + 2 * priv->sifs + + vnt_get_rsvtime(priv, pkt_type, + frame_length, rate, need_ack); break; case CTSDUR_BA: case CTSDUR_BA_F0: case CTSDUR_BA_F1: - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, - byPktType, cbFrameLength, wRate, bNeedAck); + dur_time = priv->sifs + vnt_get_rsvtime(priv, + pkt_type, frame_length, rate, need_ack); break; default: break; } - return cpu_to_le16((u16)uDurTime); + return cpu_to_le16((u16)dur_time); } -static u16 vnt_rxtx_datahead_g(struct vnt_private *priv, u8 pkt_type, u16 rate, - struct vnt_tx_datahead_g *buf, u32 frame_len, int need_ack) +static u16 vnt_mac_hdr_pos(struct vnt_usb_send_context *tx_context, + struct ieee80211_hdr *hdr) { + u8 *head = tx_context->data + offsetof(struct vnt_tx_buffer, fifo_head); + u8 *hdr_pos = (u8 *)hdr; + + tx_context->hdr = hdr; + if (!tx_context->hdr) + return 0; + + return (u16)(hdr_pos - head); +} + +static u16 vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context, + struct vnt_tx_datahead_g *buf) +{ + + struct vnt_private *priv = tx_context->priv; + struct ieee80211_hdr *hdr = + (struct ieee80211_hdr *)tx_context->skb->data; + u32 frame_len = tx_context->frame_len; + u16 rate = tx_context->tx_rate; + u8 need_ack = tx_context->need_ack; + /* Get SignalField,ServiceField,Length */ - BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a); - BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate, + vnt_get_phy_field(priv, frame_len, rate, tx_context->pkt_type, &buf->a); + vnt_get_phy_field(priv, frame_len, priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); /* Get Duration and TimeStamp */ - buf->duration_a = s_uGetDataDuration(priv, pkt_type, need_ack); - buf->duration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack); + if (ieee80211_is_pspoll(hdr->frame_control)) { + __le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15)); + + buf->duration_a = dur; + buf->duration_b = dur; + } else { + buf->duration_a = vnt_get_duration_le(priv, + tx_context->pkt_type, need_ack); + buf->duration_b = vnt_get_duration_le(priv, + PK_TYPE_11B, need_ack); + } buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate); buf->time_stamp_off_b = vnt_time_stamp_off(priv, - priv->byTopCCKBasicRate); + priv->top_cck_basic_rate); + + tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr); return le16_to_cpu(buf->duration_a); } -static u16 vnt_rxtx_datahead_g_fb(struct vnt_private *priv, u8 pkt_type, - u16 rate, struct vnt_tx_datahead_g_fb *buf, - u32 frame_len, int need_ack) +static u16 vnt_rxtx_datahead_g_fb(struct vnt_usb_send_context *tx_context, + struct vnt_tx_datahead_g_fb *buf) { + struct vnt_private *priv = tx_context->priv; + u32 frame_len = tx_context->frame_len; + u16 rate = tx_context->tx_rate; + u8 need_ack = tx_context->need_ack; + /* Get SignalField,ServiceField,Length */ - BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a); + vnt_get_phy_field(priv, frame_len, rate, tx_context->pkt_type, &buf->a); - BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate, + vnt_get_phy_field(priv, frame_len, priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); /* Get Duration and TimeStamp */ - buf->duration_a = s_uGetDataDuration(priv, pkt_type, need_ack); - buf->duration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack); + buf->duration_a = vnt_get_duration_le(priv, tx_context->pkt_type, + need_ack); + buf->duration_b = vnt_get_duration_le(priv, PK_TYPE_11B, need_ack); - buf->duration_a_f0 = s_uGetDataDuration(priv, pkt_type, need_ack); - buf->duration_a_f1 = s_uGetDataDuration(priv, pkt_type, need_ack); + buf->duration_a_f0 = vnt_get_duration_le(priv, tx_context->pkt_type, + need_ack); + buf->duration_a_f1 = vnt_get_duration_le(priv, tx_context->pkt_type, + need_ack); buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate); buf->time_stamp_off_b = vnt_time_stamp_off(priv, - priv->byTopCCKBasicRate); + priv->top_cck_basic_rate); + + tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr); return le16_to_cpu(buf->duration_a); } -static u16 vnt_rxtx_datahead_a_fb(struct vnt_private *priv, u8 pkt_type, - u16 rate, struct vnt_tx_datahead_a_fb *buf, - u32 frame_len, int need_ack) +static u16 vnt_rxtx_datahead_a_fb(struct vnt_usb_send_context *tx_context, + struct vnt_tx_datahead_a_fb *buf) { + struct vnt_private *priv = tx_context->priv; + u16 rate = tx_context->tx_rate; + u8 pkt_type = tx_context->pkt_type; + u8 need_ack = tx_context->need_ack; + u32 frame_len = tx_context->frame_len; + /* Get SignalField,ServiceField,Length */ - BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a); + vnt_get_phy_field(priv, frame_len, rate, pkt_type, &buf->a); /* Get Duration and TimeStampOff */ - buf->duration = s_uGetDataDuration(priv, pkt_type, need_ack); + buf->duration = vnt_get_duration_le(priv, pkt_type, need_ack); - buf->duration_f0 = s_uGetDataDuration(priv, pkt_type, need_ack); - buf->duration_f1 = s_uGetDataDuration(priv, pkt_type, need_ack); + buf->duration_f0 = vnt_get_duration_le(priv, pkt_type, need_ack); + buf->duration_f1 = vnt_get_duration_le(priv, pkt_type, need_ack); buf->time_stamp_off = vnt_time_stamp_off(priv, rate); + tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr); + return le16_to_cpu(buf->duration); } -static u16 vnt_rxtx_datahead_ab(struct vnt_private *priv, u8 pkt_type, - u16 rate, struct vnt_tx_datahead_ab *buf, - u32 frame_len, int need_ack) +static u16 vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context, + struct vnt_tx_datahead_ab *buf) { + struct vnt_private *priv = tx_context->priv; + struct ieee80211_hdr *hdr = + (struct ieee80211_hdr *)tx_context->skb->data; + u32 frame_len = tx_context->frame_len; + u16 rate = tx_context->tx_rate; + u8 need_ack = tx_context->need_ack; + /* Get SignalField,ServiceField,Length */ - BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->ab); + vnt_get_phy_field(priv, frame_len, rate, + tx_context->pkt_type, &buf->ab); + /* Get Duration and TimeStampOff */ - buf->duration = s_uGetDataDuration(priv, pkt_type, need_ack); + if (ieee80211_is_pspoll(hdr->frame_control)) { + __le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15)); + + buf->duration = dur; + } else { + buf->duration = vnt_get_duration_le(priv, tx_context->pkt_type, + need_ack); + } buf->time_stamp_off = vnt_time_stamp_off(priv, rate); + tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr); + return le16_to_cpu(buf->duration); } -static int vnt_fill_ieee80211_rts(struct vnt_private *priv, - struct ieee80211_rts *rts, struct ethhdr *eth_hdr, - __le16 duration) +static int vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context, + struct ieee80211_rts *rts, __le16 duration) { + struct ieee80211_hdr *hdr = + (struct ieee80211_hdr *)tx_context->skb->data; + rts->duration = duration; rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - if (priv->op_mode == NL80211_IFTYPE_ADHOC || - priv->op_mode == NL80211_IFTYPE_AP) - memcpy(rts->ra, eth_hdr->h_dest, ETH_ALEN); - else - memcpy(rts->ra, priv->abyBSSID, ETH_ALEN); - - if (priv->op_mode == NL80211_IFTYPE_AP) - memcpy(rts->ta, priv->abyBSSID, ETH_ALEN); - else - memcpy(rts->ta, eth_hdr->h_source, ETH_ALEN); + memcpy(rts->ra, hdr->addr1, ETH_ALEN); + memcpy(rts->ta, hdr->addr2, ETH_ALEN); return 0; } -static u16 vnt_rxtx_rts_g_head(struct vnt_private *priv, - struct vnt_rts_g *buf, struct ethhdr *eth_hdr, - u8 pkt_type, u32 frame_len, int need_ack, - u16 current_rate, u8 fb_option) +static u16 vnt_rxtx_rts_g_head(struct vnt_usb_send_context *tx_context, + struct vnt_rts_g *buf) { + struct vnt_private *priv = tx_context->priv; u16 rts_frame_len = 20; + u16 current_rate = tx_context->tx_rate; - BBvCalculateParameter(priv, rts_frame_len, priv->byTopCCKBasicRate, + vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); - BBvCalculateParameter(priv, rts_frame_len, - priv->byTopOFDMBasicRate, pkt_type, &buf->a); - - buf->duration_bb = s_uGetRTSCTSDuration(priv, RTSDUR_BB, frame_len, - PK_TYPE_11B, priv->byTopCCKBasicRate, need_ack, fb_option); - buf->duration_aa = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len, - pkt_type, current_rate, need_ack, fb_option); - buf->duration_ba = s_uGetRTSCTSDuration(priv, RTSDUR_BA, frame_len, - pkt_type, current_rate, need_ack, fb_option); - - vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration_aa); - - return vnt_rxtx_datahead_g(priv, pkt_type, current_rate, - &buf->data_head, frame_len, need_ack); + vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, + tx_context->pkt_type, &buf->a); + + buf->duration_bb = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BB, + PK_TYPE_11B, + priv->top_cck_basic_rate); + buf->duration_aa = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA, + tx_context->pkt_type, + current_rate); + buf->duration_ba = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BA, + tx_context->pkt_type, + current_rate); + + vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa); + + return vnt_rxtx_datahead_g(tx_context, &buf->data_head); } -static u16 vnt_rxtx_rts_g_fb_head(struct vnt_private *priv, - struct vnt_rts_g_fb *buf, struct ethhdr *eth_hdr, - u8 pkt_type, u32 frame_len, int need_ack, - u16 current_rate, u8 fb_option) +static u16 vnt_rxtx_rts_g_fb_head(struct vnt_usb_send_context *tx_context, + struct vnt_rts_g_fb *buf) { + struct vnt_private *priv = tx_context->priv; + u16 current_rate = tx_context->tx_rate; u16 rts_frame_len = 20; - BBvCalculateParameter(priv, rts_frame_len, priv->byTopCCKBasicRate, + vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); - BBvCalculateParameter(priv, rts_frame_len, - priv->byTopOFDMBasicRate, pkt_type, &buf->a); - - - buf->duration_bb = s_uGetRTSCTSDuration(priv, RTSDUR_BB, frame_len, - PK_TYPE_11B, priv->byTopCCKBasicRate, need_ack, fb_option); - buf->duration_aa = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len, - pkt_type, current_rate, need_ack, fb_option); - buf->duration_ba = s_uGetRTSCTSDuration(priv, RTSDUR_BA, frame_len, - pkt_type, current_rate, need_ack, fb_option); - - - buf->rts_duration_ba_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F0, - frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option); - buf->rts_duration_aa_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0, - frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option); - buf->rts_duration_ba_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F1, - frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option); - buf->rts_duration_aa_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1, - frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option); - - vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration_aa); - - return vnt_rxtx_datahead_g_fb(priv, pkt_type, current_rate, - &buf->data_head, frame_len, need_ack); + vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, + tx_context->pkt_type, &buf->a); + + buf->duration_bb = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BB, + PK_TYPE_11B, + priv->top_cck_basic_rate); + buf->duration_aa = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA, + tx_context->pkt_type, + current_rate); + buf->duration_ba = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BA, + tx_context->pkt_type, + current_rate); + + buf->rts_duration_ba_f0 = + vnt_get_rtscts_duration_le(tx_context, RTSDUR_BA_F0, + tx_context->pkt_type, + priv->tx_rate_fb0); + buf->rts_duration_aa_f0 = + vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA_F0, + tx_context->pkt_type, + priv->tx_rate_fb0); + buf->rts_duration_ba_f1 = + vnt_get_rtscts_duration_le(tx_context, RTSDUR_BA_F1, + tx_context->pkt_type, + priv->tx_rate_fb1); + buf->rts_duration_aa_f1 = + vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA_F1, + tx_context->pkt_type, + priv->tx_rate_fb1); + + vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa); + + return vnt_rxtx_datahead_g_fb(tx_context, &buf->data_head); } -static u16 vnt_rxtx_rts_ab_head(struct vnt_private *priv, - struct vnt_rts_ab *buf, struct ethhdr *eth_hdr, - u8 pkt_type, u32 frame_len, int need_ack, - u16 current_rate, u8 fb_option) +static u16 vnt_rxtx_rts_ab_head(struct vnt_usb_send_context *tx_context, + struct vnt_rts_ab *buf) { + struct vnt_private *priv = tx_context->priv; + u16 current_rate = tx_context->tx_rate; u16 rts_frame_len = 20; - BBvCalculateParameter(priv, rts_frame_len, - priv->byTopOFDMBasicRate, pkt_type, &buf->ab); + vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, + tx_context->pkt_type, &buf->ab); - buf->duration = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len, - pkt_type, current_rate, need_ack, fb_option); + buf->duration = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA, + tx_context->pkt_type, + current_rate); - vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration); + vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration); - return vnt_rxtx_datahead_ab(priv, pkt_type, current_rate, - &buf->data_head, frame_len, need_ack); + return vnt_rxtx_datahead_ab(tx_context, &buf->data_head); } -static u16 vnt_rxtx_rts_a_fb_head(struct vnt_private *priv, - struct vnt_rts_a_fb *buf, struct ethhdr *eth_hdr, - u8 pkt_type, u32 frame_len, int need_ack, - u16 current_rate, u8 fb_option) +static u16 vnt_rxtx_rts_a_fb_head(struct vnt_usb_send_context *tx_context, + struct vnt_rts_a_fb *buf) { + struct vnt_private *priv = tx_context->priv; + u16 current_rate = tx_context->tx_rate; u16 rts_frame_len = 20; - BBvCalculateParameter(priv, rts_frame_len, - priv->byTopOFDMBasicRate, pkt_type, &buf->a); + vnt_get_phy_field(priv, rts_frame_len, + priv->top_ofdm_basic_rate, tx_context->pkt_type, &buf->a); - buf->duration = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len, - pkt_type, current_rate, need_ack, fb_option); + buf->duration = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA, + tx_context->pkt_type, + current_rate); - buf->rts_duration_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0, - frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option); + buf->rts_duration_f0 = + vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA_F0, + tx_context->pkt_type, + priv->tx_rate_fb0); - buf->rts_duration_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1, - frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option); + buf->rts_duration_f1 = + vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA_F1, + tx_context->pkt_type, + priv->tx_rate_fb1); - vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration); + vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration); - return vnt_rxtx_datahead_a_fb(priv, pkt_type, current_rate, - &buf->data_head, frame_len, need_ack); + return vnt_rxtx_datahead_a_fb(tx_context, &buf->data_head); } -static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, - union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck, - struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption) +static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context, + union vnt_tx_data_head *head) { + struct vnt_private *priv = tx_context->priv; + u32 cts_frame_len = 14; + u16 current_rate = tx_context->tx_rate; if (!head) return 0; - /* Note: So far RTSHead doesn't appear in ATIM - * & Beacom DMA, so we don't need to take them - * into account. - * Otherwise, we need to modified codes for them. - */ - switch (byPktType) { - case PK_TYPE_11GB: - case PK_TYPE_11GA: - if (byFBOption == AUTO_FB_NONE) - return vnt_rxtx_rts_g_head(pDevice, &head->rts_g, - psEthHeader, byPktType, cbFrameLength, - bNeedAck, wCurrentRate, byFBOption); - else - return vnt_rxtx_rts_g_fb_head(pDevice, &head->rts_g_fb, - psEthHeader, byPktType, cbFrameLength, - bNeedAck, wCurrentRate, byFBOption); - break; - case PK_TYPE_11A: - if (byFBOption) { - return vnt_rxtx_rts_a_fb_head(pDevice, &head->rts_a_fb, - psEthHeader, byPktType, cbFrameLength, - bNeedAck, wCurrentRate, byFBOption); - break; - } - case PK_TYPE_11B: - return vnt_rxtx_rts_ab_head(pDevice, &head->rts_ab, - psEthHeader, byPktType, cbFrameLength, - bNeedAck, wCurrentRate, byFBOption); - } - - return 0; -} - -static u16 s_vFillCTSHead(struct vnt_private *pDevice, - u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength, - int bNeedAck, u16 wCurrentRate, u8 byFBOption) -{ - u32 uCTSFrameLen = 14; - - if (!head) - return 0; - - if (byFBOption != AUTO_FB_NONE) { + if (tx_context->fb_option) { /* Auto Fall back */ - struct vnt_cts_fb *pBuf = &head->cts_g_fb; + struct vnt_cts_fb *buf = &head->cts_g_fb; /* Get SignalField,ServiceField,Length */ - BBvCalculateParameter(pDevice, uCTSFrameLen, - pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b); - pBuf->duration_ba = s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, byFBOption); + vnt_get_phy_field(priv, cts_frame_len, + priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); + buf->duration_ba = + vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA, + tx_context->pkt_type, + current_rate); /* Get CTSDuration_ba_f0 */ - pBuf->cts_duration_ba_f0 = s_uGetRTSCTSDuration(pDevice, - CTSDUR_BA_F0, cbFrameLength, byPktType, - pDevice->tx_rate_fb0, bNeedAck, byFBOption); + buf->cts_duration_ba_f0 = + vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F0, + tx_context->pkt_type, + priv->tx_rate_fb0); /* Get CTSDuration_ba_f1 */ - pBuf->cts_duration_ba_f1 = s_uGetRTSCTSDuration(pDevice, - CTSDUR_BA_F1, cbFrameLength, byPktType, - pDevice->tx_rate_fb1, bNeedAck, byFBOption); + buf->cts_duration_ba_f1 = + vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F1, + tx_context->pkt_type, + priv->tx_rate_fb1); /* Get CTS Frame body */ - pBuf->data.duration = pBuf->duration_ba; - pBuf->data.frame_control = + buf->data.duration = buf->duration_ba; + buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); - memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN); + memcpy(buf->data.ra, priv->current_net_addr, ETH_ALEN); - return vnt_rxtx_datahead_g_fb(pDevice, byPktType, wCurrentRate, - &pBuf->data_head, cbFrameLength, bNeedAck); + return vnt_rxtx_datahead_g_fb(tx_context, &buf->data_head); } else { - struct vnt_cts *pBuf = &head->cts_g; + struct vnt_cts *buf = &head->cts_g; /* Get SignalField,ServiceField,Length */ - BBvCalculateParameter(pDevice, uCTSFrameLen, - pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b); + vnt_get_phy_field(priv, cts_frame_len, + priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); /* Get CTSDuration_ba */ - pBuf->duration_ba = s_uGetRTSCTSDuration(pDevice, - CTSDUR_BA, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, byFBOption); + buf->duration_ba = + vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA, + tx_context->pkt_type, + current_rate); /*Get CTS Frame body*/ - pBuf->data.duration = pBuf->duration_ba; - pBuf->data.frame_control = + buf->data.duration = buf->duration_ba; + buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); - memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN); + memcpy(buf->data.ra, priv->current_net_addr, ETH_ALEN); - return vnt_rxtx_datahead_g(pDevice, byPktType, wCurrentRate, - &pBuf->data_head, cbFrameLength, bNeedAck); + return vnt_rxtx_datahead_g(tx_context, &buf->data_head); } return 0; } -/*+ - * - * Description: - * Generate FIFO control for MAC & Baseband controller - * - * Parameters: - * In: - * pDevice - Pointer to adpater - * pTxDataHead - Transmit Data Buffer - * pTxBufHead - pTxBufHead - * pvRrvTime - pvRrvTime - * pvRTS - RTS Buffer - * pCTS - CTS Buffer - * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS) - * bNeedACK - If need ACK - * Out: - * none - * - * Return Value: none - * --*/ +static u16 vnt_rxtx_rts(struct vnt_usb_send_context *tx_context, + union vnt_tx_head *tx_head, bool need_mic) +{ + struct vnt_private *priv = tx_context->priv; + struct vnt_rrv_time_rts *buf = &tx_head->tx_rts.rts; + union vnt_tx_data_head *head = &tx_head->tx_rts.tx.head; + u32 frame_len = tx_context->frame_len; + u16 current_rate = tx_context->tx_rate; + u8 need_ack = tx_context->need_ack; + + buf->rts_rrv_time_aa = vnt_get_rtscts_rsvtime_le(priv, 2, + tx_context->pkt_type, frame_len, current_rate); + buf->rts_rrv_time_ba = vnt_get_rtscts_rsvtime_le(priv, 1, + tx_context->pkt_type, frame_len, current_rate); + buf->rts_rrv_time_bb = vnt_get_rtscts_rsvtime_le(priv, 0, + tx_context->pkt_type, frame_len, current_rate); + + buf->rrv_time_a = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type, + frame_len, current_rate, + need_ack); + buf->rrv_time_b = vnt_rxtx_rsvtime_le16(priv, PK_TYPE_11B, frame_len, + priv->top_cck_basic_rate, need_ack); + + if (need_mic) + head = &tx_head->tx_rts.tx.mic.head; + + if (tx_context->fb_option) + return vnt_rxtx_rts_g_fb_head(tx_context, &head->rts_g_fb); + + return vnt_rxtx_rts_g_head(tx_context, &head->rts_g); +} -static u16 s_vGenerateTxParameter(struct vnt_private *pDevice, - u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer, - struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize, - int bNeedACK, struct ethhdr *psEthHeader, bool need_rts) +static u16 vnt_rxtx_cts(struct vnt_usb_send_context *tx_context, + union vnt_tx_head *tx_head, bool need_mic) { - struct vnt_tx_fifo_head *pFifoHead = &tx_buffer->fifo_head; - union vnt_tx_data_head *head = NULL; - u16 wFifoCtl; - u8 byFBOption = AUTO_FB_NONE; + struct vnt_private *priv = tx_context->priv; + struct vnt_rrv_time_cts *buf = &tx_head->tx_cts.cts; + union vnt_tx_data_head *head = &tx_head->tx_cts.tx.head; + u32 frame_len = tx_context->frame_len; + u16 current_rate = tx_context->tx_rate; + u8 need_ack = tx_context->need_ack; + + buf->rrv_time_a = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type, + frame_len, current_rate, need_ack); + buf->rrv_time_b = vnt_rxtx_rsvtime_le16(priv, PK_TYPE_11B, + frame_len, priv->top_cck_basic_rate, need_ack); + + buf->cts_rrv_time_ba = vnt_get_rtscts_rsvtime_le(priv, 3, + tx_context->pkt_type, frame_len, current_rate); + + if (need_mic) + head = &tx_head->tx_cts.tx.mic.head; + + /* Fill CTS */ + return vnt_fill_cts_head(tx_context, head); +} - pFifoHead->current_rate = cpu_to_le16(wCurrentRate); - wFifoCtl = pFifoHead->wFIFOCtl; +static u16 vnt_rxtx_ab(struct vnt_usb_send_context *tx_context, + union vnt_tx_head *tx_head, bool need_rts, bool need_mic) +{ + struct vnt_private *priv = tx_context->priv; + struct vnt_rrv_time_ab *buf = &tx_head->tx_ab.ab; + union vnt_tx_data_head *head = &tx_head->tx_ab.tx.head; + u32 frame_len = tx_context->frame_len; + u16 current_rate = tx_context->tx_rate; + u8 need_ack = tx_context->need_ack; + + buf->rrv_time = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type, + frame_len, current_rate, need_ack); + + if (need_mic) + head = &tx_head->tx_ab.tx.mic.head; + + if (need_rts) { + if (tx_context->pkt_type == PK_TYPE_11B) + buf->rts_rrv_time = vnt_get_rtscts_rsvtime_le(priv, 0, + tx_context->pkt_type, frame_len, current_rate); + else /* PK_TYPE_11A */ + buf->rts_rrv_time = vnt_get_rtscts_rsvtime_le(priv, 2, + tx_context->pkt_type, frame_len, current_rate); + + if (tx_context->fb_option && + tx_context->pkt_type == PK_TYPE_11A) + return vnt_rxtx_rts_a_fb_head(tx_context, + &head->rts_a_fb); + + return vnt_rxtx_rts_ab_head(tx_context, &head->rts_ab); + } - if (wFifoCtl & FIFOCTL_AUTO_FB_0) - byFBOption = AUTO_FB_0; - else if (wFifoCtl & FIFOCTL_AUTO_FB_1) - byFBOption = AUTO_FB_1; + if (tx_context->pkt_type == PK_TYPE_11A) + return vnt_rxtx_datahead_a_fb(tx_context, + &head->data_head_a_fb); - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { + return vnt_rxtx_datahead_ab(tx_context, &head->data_head_ab); +} + +static u16 vnt_generate_tx_parameter(struct vnt_usb_send_context *tx_context, + struct vnt_tx_buffer *tx_buffer, + struct vnt_mic_hdr **mic_hdr, u32 need_mic, + bool need_rts) +{ + + if (tx_context->pkt_type == PK_TYPE_11GB || + tx_context->pkt_type == PK_TYPE_11GA) { if (need_rts) { - struct vnt_rrv_time_rts *pBuf = - &tx_buffer->tx_head.tx_rts.rts; - - pBuf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, - byPktType, cbFrameSize, wCurrentRate); - pBuf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, - byPktType, cbFrameSize, wCurrentRate); - pBuf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, - byPktType, cbFrameSize, wCurrentRate); - - pBuf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, - byPktType, cbFrameSize, wCurrentRate, bNeedACK); - pBuf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, - PK_TYPE_11B, cbFrameSize, - pDevice->byTopCCKBasicRate, bNeedACK); - - if (need_mic) { + if (need_mic) *mic_hdr = &tx_buffer-> tx_head.tx_rts.tx.mic.hdr; - head = &tx_buffer->tx_head.tx_rts.tx.mic.head; - } else { - head = &tx_buffer->tx_head.tx_rts.tx.head; - } - - /* Fill RTS */ - return s_vFillRTSHead(pDevice, byPktType, head, - cbFrameSize, bNeedACK, psEthHeader, - wCurrentRate, byFBOption); - - } else { - struct vnt_rrv_time_cts *pBuf = &tx_buffer-> - tx_head.tx_cts.cts; - - pBuf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, - byPktType, cbFrameSize, wCurrentRate, bNeedACK); - pBuf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, - PK_TYPE_11B, cbFrameSize, - pDevice->byTopCCKBasicRate, bNeedACK); - - pBuf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, - byPktType, cbFrameSize, wCurrentRate); - - if (need_mic) { - *mic_hdr = &tx_buffer-> - tx_head.tx_cts.tx.mic.hdr; - head = &tx_buffer->tx_head.tx_cts.tx.mic.head; - } else { - head = &tx_buffer->tx_head.tx_cts.tx.head; - } - - /* Fill CTS */ - return s_vFillCTSHead(pDevice, byPktType, - head, cbFrameSize, bNeedACK, wCurrentRate, - byFBOption); - } - } else if (byPktType == PK_TYPE_11A) { - if (need_mic) { - *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr; - head = &tx_buffer->tx_head.tx_ab.tx.mic.head; - } else { - head = &tx_buffer->tx_head.tx_ab.tx.head; - } - if (need_rts) { - struct vnt_rrv_time_ab *pBuf = &tx_buffer-> - tx_head.tx_ab.ab; - - pBuf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, - byPktType, cbFrameSize, wCurrentRate); - - pBuf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, - byPktType, cbFrameSize, wCurrentRate, bNeedACK); - - /* Fill RTS */ - return s_vFillRTSHead(pDevice, byPktType, head, - cbFrameSize, bNeedACK, psEthHeader, - wCurrentRate, byFBOption); - } else { - struct vnt_rrv_time_ab *pBuf = &tx_buffer-> - tx_head.tx_ab.ab; - - pBuf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, - PK_TYPE_11A, cbFrameSize, - wCurrentRate, bNeedACK); - - return vnt_rxtx_datahead_a_fb(pDevice, byPktType, - wCurrentRate, &head->data_head_a_fb, - cbFrameSize, bNeedACK); - } - } else if (byPktType == PK_TYPE_11B) { - if (need_mic) { - *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr; - head = &tx_buffer->tx_head.tx_ab.tx.mic.head; - } else { - head = &tx_buffer->tx_head.tx_ab.tx.head; + return vnt_rxtx_rts(tx_context, &tx_buffer->tx_head, + need_mic); } - if (need_rts) { - struct vnt_rrv_time_ab *pBuf = &tx_buffer-> - tx_head.tx_ab.ab; - - pBuf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, - byPktType, cbFrameSize, wCurrentRate); - - pBuf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, - PK_TYPE_11B, cbFrameSize, wCurrentRate, - bNeedACK); - - /* Fill RTS */ - return s_vFillRTSHead(pDevice, byPktType, head, - cbFrameSize, - bNeedACK, psEthHeader, wCurrentRate, byFBOption); - } else { - struct vnt_rrv_time_ab *pBuf = &tx_buffer-> - tx_head.tx_ab.ab; - - pBuf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, - PK_TYPE_11B, cbFrameSize, - wCurrentRate, bNeedACK); - - return vnt_rxtx_datahead_ab(pDevice, byPktType, - wCurrentRate, &head->data_head_ab, - cbFrameSize, bNeedACK); - } + if (need_mic) + *mic_hdr = &tx_buffer->tx_head.tx_cts.tx.mic.hdr; + + return vnt_rxtx_cts(tx_context, &tx_buffer->tx_head, need_mic); } - return 0; + if (need_mic) + *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr; + + return vnt_rxtx_ab(tx_context, &tx_buffer->tx_head, need_rts, need_mic); } -/* - u8 * pbyBuffer,//point to pTxBufHead - u16 wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last - unsigned int cbFragmentSize,//Hdr+payoad+FCS -*/ - -static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, - struct vnt_tx_buffer *tx_buffer, int bNeedEncryption, - u32 uSkbPacketLen, struct ethhdr *psEthHeader, - u8 *pPacket, PSKeyItem pTransmitKey, u32 uNodeIndex, u16 wCurrentRate, - u32 *pcbHeaderLen, u32 *pcbTotalLen) -{ - struct vnt_tx_fifo_head *pTxBufHead = &tx_buffer->fifo_head; - u32 cbFrameSize, cbFrameBodySize; - u32 cb802_1_H_len; - u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbMACHdLen = 0; - u32 cbFCSlen = 4, cbMICHDR = 0; - int bNeedACK; - bool bRTS = false; - u8 *pbyType, *pbyMacHdr, *pbyIVHead, *pbyPayloadHead, *pbyTxBufferAddr; - u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; - u8 abySNAP_Bridgetunnel[ETH_ALEN] - = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; - u32 uDuration; - u32 cbHeaderLength = 0, uPadding = 0; - struct vnt_mic_hdr *pMICHDR; - u8 byFBOption = AUTO_FB_NONE, byFragType; - u16 wTxBufSize; - u32 dwMICKey0, dwMICKey1, dwMIC_Priority; - u32 *pdwMIC_L, *pdwMIC_R; - int bSoftWEP = false; - - pMICHDR = NULL; - - if (bNeedEncryption && pTransmitKey->pvKeyTable) { - if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true) - bSoftWEP = true; /* WEP 256 */ - } - /* Get pkt type */ - if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) - cb802_1_H_len = 8; - else - cb802_1_H_len = 0; - - cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len; - - //Set packet type - pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8); - - if (pDevice->op_mode == NL80211_IFTYPE_ADHOC || - pDevice->op_mode == NL80211_IFTYPE_AP) { - if (is_multicast_ether_addr(psEthHeader->h_dest)) { - bNeedACK = false; - pTxBufHead->wFIFOCtl = - pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK); - } else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; +static void vnt_fill_txkey(struct vnt_usb_send_context *tx_context, + u8 *key_buffer, struct ieee80211_key_conf *tx_key, struct sk_buff *skb, + u16 payload_len, struct vnt_mic_hdr *mic_hdr) +{ + struct ieee80211_hdr *hdr = tx_context->hdr; + struct ieee80211_key_seq seq; + u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb)); + + /* strip header and icv len from payload */ + payload_len -= ieee80211_get_hdrlen_from_skb(skb); + payload_len -= tx_key->icv_len; + + switch (tx_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + memcpy(key_buffer, iv, 3); + memcpy(key_buffer + 3, tx_key->key, tx_key->keylen); + + if (tx_key->keylen == WLAN_KEY_LEN_WEP40) { + memcpy(key_buffer + 8, iv, 3); + memcpy(key_buffer + 11, + tx_key->key, WLAN_KEY_LEN_WEP40); } - } else { - /* MSDUs in Infra mode always need ACK */ - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - } - pTxBufHead->time_stamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); + break; + case WLAN_CIPHER_SUITE_TKIP: + ieee80211_get_tkip_p2k(tx_key, skb, key_buffer); - //Set FRAGCTL_MACHDCNT - cbMACHdLen = WLAN_HDR_ADDR3_LEN; + break; + case WLAN_CIPHER_SUITE_CCMP: - pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10); + if (!mic_hdr) + return; - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - } + mic_hdr->id = 0x59; + mic_hdr->payload_len = cpu_to_be16(payload_len); + memcpy(mic_hdr->mic_addr2, hdr->addr2, ETH_ALEN); - /* Set Auto Fallback Ctl */ - if (wCurrentRate >= RATE_18M) { - if (pDevice->byAutoFBCtrl == AUTO_FB_0) { - pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0; + ieee80211_get_key_tx_seq(tx_key, &seq); - pDevice->tx_rate_fb0 = - wFB_Opt0[FB_RATE0][wCurrentRate - RATE_18M]; - pDevice->tx_rate_fb1 = - wFB_Opt0[FB_RATE1][wCurrentRate - RATE_18M]; + memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN); - byFBOption = AUTO_FB_0; - } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) { - pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1; - pDevice->tx_rate_fb0 = - wFB_Opt1[FB_RATE0][wCurrentRate - RATE_18M]; - pDevice->tx_rate_fb1 = - wFB_Opt1[FB_RATE1][wCurrentRate - RATE_18M]; + if (ieee80211_has_a4(hdr->frame_control)) + mic_hdr->hlen = cpu_to_be16(28); + else + mic_hdr->hlen = cpu_to_be16(22); - byFBOption = AUTO_FB_1; - } - } + memcpy(mic_hdr->addr1, hdr->addr1, ETH_ALEN); + memcpy(mic_hdr->addr2, hdr->addr2, ETH_ALEN); + memcpy(mic_hdr->addr3, hdr->addr3, ETH_ALEN); - if (bSoftWEP != true) { - if ((bNeedEncryption) && (pTransmitKey != NULL)) { //WEP enabled - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104 - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } - if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n"); - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - } - else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP - pTxBufHead->wFragCtl |= FRAGCTL_AES; - } - } - } + mic_hdr->frame_control = cpu_to_le16( + le16_to_cpu(hdr->frame_control) & 0xc78f); + mic_hdr->seq_ctrl = cpu_to_le16( + le16_to_cpu(hdr->seq_ctrl) & 0xf); + + if (ieee80211_has_a4(hdr->frame_control)) + memcpy(mic_hdr->addr4, hdr->addr4, ETH_ALEN); - if ((bNeedEncryption) && (pTransmitKey != NULL)) { - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - cbIVlen = 4; - cbICVlen = 4; - } - else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } - if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - cbMICHDR = sizeof(struct vnt_mic_hdr); - } - if (bSoftWEP == false) { - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMACHdLen%4); - uPadding %= 4; - } - } - - cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; - - if ( (bNeedACK == false) ||(cbFrameSize < pDevice->wRTSThreshold) ) { - bRTS = false; - } else { - bRTS = true; - pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY); - } - - pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]); - wTxBufSize = sizeof(struct vnt_tx_fifo_head); - - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet - if (byFBOption == AUTO_FB_NONE) { - if (bRTS == true) {//RTS_need - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) + - cbMICHDR + sizeof(struct vnt_rts_g); - } - else { //RTS_needless - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - cbMICHDR + sizeof(struct vnt_cts); - } - } else { - // Auto Fall Back - if (bRTS == true) {//RTS_need - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) + - cbMICHDR + sizeof(struct vnt_rts_g_fb); - } - else if (bRTS == false) { //RTS_needless - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - cbMICHDR + sizeof(struct vnt_cts_fb); - } - } // Auto Fall Back - } - else {//802.11a/b packet - if (byFBOption == AUTO_FB_NONE) { - if (bRTS == true) {//RTS_need - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_rts_ab); - } - else if (bRTS == false) { //RTS_needless, no MICHDR - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_tx_datahead_ab); - } - } else { - // Auto Fall Back - if (bRTS == true) {//RTS_need - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_rts_a_fb); - } - else if (bRTS == false) { //RTS_needless - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb); - } - } // Auto Fall Back - } - - pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderLength); - pbyIVHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding); - pbyPayloadHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen); - - //========================= - // No Fragmentation - //========================= - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n"); - byFragType = FRAGCTL_NONFRAG; - //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]); - - /* Fill FIFO, RrvTime, RTS and CTS */ - uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, - tx_buffer, &pMICHDR, cbMICHDR, - cbFrameSize, bNeedACK, psEthHeader, bRTS); - - // Generate TX MAC Header - s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption, - byFragType, 0); - - if (bNeedEncryption == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey, - pbyMacHdr, (u16)cbFrameBodySize, pMICHDR); - } - - /* 802.1H */ - if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) { - if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) || - (psEthHeader->h_proto == cpu_to_le16(0xF380))) - memcpy((u8 *) (pbyPayloadHead), - abySNAP_Bridgetunnel, 6); - else - memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6); - pbyType = (u8 *) (pbyPayloadHead + 6); + memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP); - memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16)); + break; + default: + break; } - if (pPacket != NULL) { - // Copy the Packet into a tx Buffer - memcpy((pbyPayloadHead + cb802_1_H_len), - (pPacket + ETH_HLEN), - uSkbPacketLen - ETH_HLEN - ); +} - } else { - // while bRelayPacketSend psEthHeader is point to header+payload - memcpy((pbyPayloadHead + cb802_1_H_len), ((u8 *)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN); - } +int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *tx_rate = &info->control.rates[0]; + struct ieee80211_rate *rate; + struct ieee80211_key_conf *tx_key; + struct ieee80211_hdr *hdr; + struct vnt_mic_hdr *mic_hdr = NULL; + struct vnt_tx_buffer *tx_buffer; + struct vnt_tx_fifo_head *tx_buffer_head; + struct vnt_usb_send_context *tx_context; + unsigned long flags; + u16 tx_bytes, tx_header_size, tx_body_size, current_rate, duration_id; + u8 pkt_type, fb_option = AUTO_FB_NONE; + bool need_rts = false, is_pspoll = false; + bool need_mic = false; - if ((bNeedEncryption == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { + hdr = (struct ieee80211_hdr *)(skb->data); - /////////////////////////////////////////////////////////////////// + rate = ieee80211_get_tx_rate(priv->hw, info); - if (pDevice->vnt_mgmt.eAuthenMode == WMAC_AUTH_WPANONE) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); + current_rate = rate->hw_value; + if (priv->current_rate != current_rate && + !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { + priv->current_rate = current_rate; + vnt_schedule_command(priv, WLAN_CMD_SETPOWER); } - else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - } - else { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]); - } - // DO Software Michael - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((u8 *)&(psEthHeader->h_dest[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((u8 *)&dwMIC_Priority, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n", - dwMICKey0, dwMICKey1); - - /////////////////////////////////////////////////////////////////// - - //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength)); - //for (ii = 0; ii < cbFrameBodySize; ii++) { - // DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii)))); - //} - //DBG_PRN_GRP12(("\n\n\n")); - - MIC_vAppend(pbyPayloadHead, cbFrameBodySize); - - pdwMIC_L = (u32 *)(pbyPayloadHead + cbFrameBodySize); - pdwMIC_R = (u32 *)(pbyPayloadHead + cbFrameBodySize + 4); - - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - MIC_vUnInit(); - - if (pDevice->bTxMICFail == true) { - *pdwMIC_L = 0; - *pdwMIC_R = 0; - pDevice->bTxMICFail = false; - } - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize); - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen); - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R); - } - if (bSoftWEP == true) { + if (current_rate > RATE_11M) + pkt_type = priv->packet_type; + else + pkt_type = PK_TYPE_11B; - s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (u16)(cbFrameBodySize + cbMIClen)); + spin_lock_irqsave(&priv->lock, flags); - } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == true)) || - ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == true)) || - ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == true)) ) { - cbFrameSize -= cbICVlen; - } + tx_context = vnt_get_free_context(priv); + if (!tx_context) { + dev_dbg(&priv->usb->dev, "%s No free context\n", __func__); + spin_unlock_irqrestore(&priv->lock, flags); + return -ENOMEM; + } - cbFrameSize -= cbFCSlen; + tx_context->skb = skb; + tx_context->pkt_type = pkt_type; + tx_context->need_ack = false; + tx_context->frame_len = skb->len + 4; + tx_context->tx_rate = current_rate; + + spin_unlock_irqrestore(&priv->lock, flags); + + tx_buffer = (struct vnt_tx_buffer *)tx_context->data; + tx_buffer_head = &tx_buffer->fifo_head; + tx_body_size = skb->len; + + /*Set fifo controls */ + if (pkt_type == PK_TYPE_11A) + tx_buffer_head->fifo_ctl = 0; + else if (pkt_type == PK_TYPE_11B) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B); + else if (pkt_type == PK_TYPE_11GB) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB); + else if (pkt_type == PK_TYPE_11GA) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA); + + if (!ieee80211_is_data(hdr->frame_control)) { + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT | + FIFOCTL_ISDMA0); + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN); + + tx_buffer_head->time_stamp = + cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); + } else { + tx_buffer_head->time_stamp = + cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); + } - *pcbHeaderLen = cbHeaderLength; - *pcbTotalLen = cbHeaderLength + cbFrameSize ; + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK); + tx_context->need_ack = true; + } - //Set FragCtl in TxBufferHead - pTxBufHead->wFragCtl |= (u16)byFragType; + if (ieee80211_has_retry(hdr->frame_control)) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY); - return true; + if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + priv->preamble_type = PREAMBLE_SHORT; + else + priv->preamble_type = PREAMBLE_LONG; -} + if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS) { + need_rts = true; + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS); + } -/*+ - * - * Description: - * Translate 802.3 to 802.11 header - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * dwTxBufferAddr - Transmit Buffer - * pPacket - Packet from upper layer - * cbPacketSize - Transmit Data Length - * Out: - * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header - * pcbAppendPayload - size of append payload for 802.1H translation - * - * Return Value: none - * --*/ + if (ieee80211_has_a4(hdr->frame_control)) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD); -static void s_vGenerateMACHeader(struct vnt_private *pDevice, - u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader, - int bNeedEncrypt, u16 wFragType, u32 uFragIdx) -{ - struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyBufferAddr; - - pMACHeader->frame_control = TYPE_802_11_DATA; - - if (pDevice->op_mode == NL80211_IFTYPE_AP) { - memcpy(&(pMACHeader->addr1[0]), - &(psEthHeader->h_dest[0]), - ETH_ALEN); - memcpy(&(pMACHeader->addr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - memcpy(&(pMACHeader->addr3[0]), - &(psEthHeader->h_source[0]), - ETH_ALEN); - pMACHeader->frame_control |= FC_FROMDS; - } else { - if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) { - memcpy(&(pMACHeader->addr1[0]), - &(psEthHeader->h_dest[0]), - ETH_ALEN); - memcpy(&(pMACHeader->addr2[0]), - &(psEthHeader->h_source[0]), - ETH_ALEN); - memcpy(&(pMACHeader->addr3[0]), - &(pDevice->abyBSSID[0]), - ETH_ALEN); - } else { - memcpy(&(pMACHeader->addr3[0]), - &(psEthHeader->h_dest[0]), - ETH_ALEN); - memcpy(&(pMACHeader->addr2[0]), - &(psEthHeader->h_source[0]), - ETH_ALEN); - memcpy(&(pMACHeader->addr1[0]), - &(pDevice->abyBSSID[0]), - ETH_ALEN); - pMACHeader->frame_control |= FC_TODS; - } - } + if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) + is_pspoll = true; - if (bNeedEncrypt) - pMACHeader->frame_control |= cpu_to_le16((u16)WLAN_SET_FC_ISWEP(1)); + tx_buffer_head->frag_ctl = + cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10); - pMACHeader->duration_id = cpu_to_le16(wDuration); + if (info->control.hw_key) { + tx_key = info->control.hw_key; + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY); + break; + case WLAN_CIPHER_SUITE_TKIP: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP); + break; + case WLAN_CIPHER_SUITE_CCMP: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES); + need_mic = true; + default: + break; + } + tx_context->frame_len += tx_key->icv_len; + } - pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4); + tx_buffer_head->current_rate = cpu_to_le16(current_rate); - //Set FragNumber in Sequence Control - pMACHeader->seq_ctrl |= cpu_to_le16((u16)uFragIdx); + /* legacy rates TODO use ieee80211_tx_rate */ + if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) { + if (priv->auto_fb_ctrl == AUTO_FB_0) { + tx_buffer_head->fifo_ctl |= + cpu_to_le16(FIFOCTL_AUTO_FB_0); - if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) { - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - } + priv->tx_rate_fb0 = + vnt_fb_opt0[FB_RATE0][current_rate - RATE_18M]; + priv->tx_rate_fb1 = + vnt_fb_opt0[FB_RATE1][current_rate - RATE_18M]; - if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag - pMACHeader->frame_control |= FC_MOREFRAG; - } -} + fb_option = AUTO_FB_0; + } else if (priv->auto_fb_ctrl == AUTO_FB_1) { + tx_buffer_head->fifo_ctl |= + cpu_to_le16(FIFOCTL_AUTO_FB_1); -/*+ - * - * Description: - * Request instructs a MAC to transmit a 802.11 management packet through - * the adapter onto the medium. - * - * Parameters: - * In: - * hDeviceContext - Pointer to the adapter - * pPacket - A pointer to a descriptor for the packet to transmit - * Out: - * none - * - * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise false - * --*/ + priv->tx_rate_fb0 = + vnt_fb_opt1[FB_RATE0][current_rate - RATE_18M]; + priv->tx_rate_fb1 = + vnt_fb_opt1[FB_RATE1][current_rate - RATE_18M]; -CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, - struct vnt_tx_mgmt *pPacket) -{ - struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; - struct vnt_tx_buffer *pTX_Buffer; - struct vnt_usb_send_context *pContext; - struct vnt_tx_fifo_head *pTxBufHead; - struct ieee80211_hdr *pMACHeader; - struct ethhdr sEthHeader; - u8 byPktType, *pbyTxBufferAddr; - struct vnt_mic_hdr *pMICHDR = NULL; - u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize; - int bNeedACK, bIsPSPOLL = false; - u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4; - u32 uPadding = 0; - u16 wTxBufSize; - u32 cbMacHdLen; - u16 wCurrentRate = RATE_1M; - unsigned long flags; + fb_option = AUTO_FB_1; + } + } - if (pDevice->byBBType == BB_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_1M; - byPktType = PK_TYPE_11B; + tx_context->fb_option = fb_option; + + duration_id = vnt_generate_tx_parameter(tx_context, tx_buffer, &mic_hdr, + need_mic, need_rts); + + tx_header_size = tx_context->tx_hdr_size; + if (!tx_header_size) { + tx_context->in_use = false; + return -ENOMEM; } - if (pMgmt->eScanState != WMAC_NO_SCANNING) - vnt_rf_setpower(pDevice, wCurrentRate, pDevice->byCurrentCh); - else - vnt_rf_setpower(pDevice, wCurrentRate, pMgmt->uCurrChannel); + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG); - pDevice->wCurrentRate = wCurrentRate; + tx_bytes = tx_header_size + tx_body_size; - spin_lock_irqsave(&pDevice->lock, flags); + memcpy(tx_context->hdr, skb->data, tx_body_size); - pContext = s_vGetFreeContext(pDevice); - if (!pContext) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "ManagementSend TX...NO CONTEXT!\n"); - spin_unlock_irqrestore(&pDevice->lock, flags); - return CMD_STATUS_RESOURCES; - } + hdr->duration_id = cpu_to_le16(duration_id); - pTX_Buffer = (struct vnt_tx_buffer *)&pContext->data[0]; - cbFrameBodySize = pPacket->cbPayloadLen; - pTxBufHead = &pTX_Buffer->fifo_head; - pbyTxBufferAddr = (u8 *)&pTxBufHead->adwTxKey[0]; - wTxBufSize = sizeof(struct vnt_tx_fifo_head); - - - //Set packet type - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - pTxBufHead->wFIFOCtl = 0; - } - else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - } - else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - } - else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; - } - - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->time_stamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); - - if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) { - bNeedACK = false; - } - else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - }; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) { - - pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; - //Set Preamble type always long - //pDevice->byPreambleType = PREAMBLE_LONG; - // probe-response don't retry - //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) { - // bNeedACK = false; - // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK); - //} - } - - pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); - - if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { - bIsPSPOLL = true; - cbMacHdLen = WLAN_HDR_ADDR2_LEN; - } else { - cbMacHdLen = WLAN_HDR_ADDR3_LEN; - } - - //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((u16)(cbMacHdLen << 10)); - - // Notes: - // Although spec says MMPDU can be fragmented; In most case, - // no one will send a MMPDU under fragmentation. With RTS may occur. - - if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { - cbIVlen = 4; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - //We need to get seed here for filling TxKey entry. - //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, - // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); - } - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - pTxBufHead->wFragCtl |= FRAGCTL_AES; - } - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMacHdLen%4); - uPadding %= 4; - } - - cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen; - - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - } - //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() - - //Set RrvTime/RTS/CTS Buffer - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - sizeof(struct vnt_cts); - } - else { // 802.11a/b packet - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - sizeof(struct vnt_tx_datahead_ab); - } - - memcpy(&(sEthHeader.h_dest[0]), - &(pPacket->p80211Header->sA3.abyAddr1[0]), - ETH_ALEN); - memcpy(&(sEthHeader.h_source[0]), - &(pPacket->p80211Header->sA3.abyAddr2[0]), - ETH_ALEN); - //========================= - // No Fragmentation - //========================= - pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG; - - /* Fill FIFO,RrvTime,RTS,and CTS */ - uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, - pTX_Buffer, &pMICHDR, 0, - cbFrameSize, bNeedACK, &sEthHeader, false); - - pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize); - - cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize; - - if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { - u8 * pbyIVHead; - u8 * pbyPayloadHead; - u8 * pbyBSSID; - PSKeyItem pTransmitKey = NULL; - - pbyIVHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding); - pbyPayloadHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen); - do { - if (pDevice->op_mode == NL80211_IFTYPE_STATION && - pDevice->bLinkPass == true) { - pbyBSSID = pDevice->abyBSSID; - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { - // get group key - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n"); - break; - } - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n"); - break; - } - } - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->op_mode); - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n"); - } - } while(false); - //Fill TXKEY - s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey, - (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL); - - memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen); - memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen), - cbFrameBodySize); - } - else { - // Copy the Packet into a tx Buffer - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - } - - pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++ ; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - if (bIsPSPOLL) { - // The MAC will automatically replace the Duration-field of MAC header by Duration-field - // of FIFO control header. - // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is - // in the same place of other packet's Duration-field). - // And it will cause Cisco-AP to issue Disassociation-packet - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head. - tx_cts.tx.head.cts_g.data_head; - data_head->duration_a = - cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - data_head->duration_b = - cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - } else { - struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head. - tx_ab.tx.head.data_head_ab; - data_head->duration = - cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); + if (info->control.hw_key) { + tx_key = info->control.hw_key; + if (tx_key->keylen > 0) + vnt_fill_txkey(tx_context, tx_buffer_head->tx_key, + tx_key, skb, tx_body_size, mic_hdr); } - } - pTX_Buffer->tx_byte_count = cpu_to_le16((u16)(cbReqCount)); - pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); - pTX_Buffer->byType = 0x00; + priv->seq_counter = (le16_to_cpu(hdr->seq_ctrl) & + IEEE80211_SCTL_SEQ) >> 4; - pContext->skb = NULL; - pContext->type = CONTEXT_MGMT_PACKET; - pContext->buf_len = (u16)cbReqCount + 4; /* USB header */ + tx_buffer->tx_byte_count = cpu_to_le16(tx_bytes); + tx_buffer->pkt_no = tx_context->pkt_no; + tx_buffer->type = 0x00; - if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) { - s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F), - &pMACHeader->addr1[0], (u16)cbFrameSize, - pTxBufHead->wFIFOCtl); - } - else { - s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F), - &pMACHeader->addr3[0], (u16)cbFrameSize, - pTxBufHead->wFIFOCtl); - } + tx_bytes += 4; - PIPEnsSendBulkOut(pDevice,pContext); + tx_context->type = CONTEXT_DATA_PACKET; + tx_context->buf_len = tx_bytes; - spin_unlock_irqrestore(&pDevice->lock, flags); + spin_lock_irqsave(&priv->lock, flags); - return CMD_STATUS_PENDING; + if (vnt_tx_context(priv, tx_context) != STATUS_PENDING) { + spin_unlock_irqrestore(&priv->lock, flags); + return -EIO; + } + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; } -CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, - struct vnt_tx_mgmt *pPacket) +static int vnt_beacon_xmit(struct vnt_private *priv, + struct sk_buff *skb) { - struct vnt_beacon_buffer *pTX_Buffer; + struct vnt_beacon_buffer *beacon_buffer; struct vnt_tx_short_buf_head *short_head; - u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; - u32 cbHeaderSize = 0; - struct ieee80211_hdr *pMACHeader; - u16 wCurrentRate; - u32 cbFrameBodySize; - u32 cbReqCount; - struct vnt_usb_send_context *pContext; - CMD_STATUS status; + struct ieee80211_tx_info *info; + struct vnt_usb_send_context *context; + struct ieee80211_mgmt *mgmt_hdr; + unsigned long flags; + u32 frame_size = skb->len + 4; + u16 current_rate, count; + + spin_lock_irqsave(&priv->lock, flags); - pContext = s_vGetFreeContext(pDevice); - if (NULL == pContext) { - status = CMD_STATUS_RESOURCES; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n"); - return status ; - } + context = vnt_get_free_context(priv); + if (!context) { + dev_dbg(&priv->usb->dev, "%s No free context!\n", __func__); + spin_unlock_irqrestore(&priv->lock, flags); + return -ENOMEM; + } - pTX_Buffer = (struct vnt_beacon_buffer *)&pContext->data[0]; - short_head = &pTX_Buffer->short_head; + context->skb = skb; - cbFrameBodySize = pPacket->cbPayloadLen; + spin_unlock_irqrestore(&priv->lock, flags); - cbHeaderSize = sizeof(struct vnt_tx_short_buf_head); + beacon_buffer = (struct vnt_beacon_buffer *)&context->data[0]; + short_head = &beacon_buffer->short_head; - if (pDevice->byBBType == BB_TYPE_11A) { - wCurrentRate = RATE_6M; + if (priv->bb_type == BB_TYPE_11A) { + current_rate = RATE_6M; /* Get SignalField,ServiceField,Length */ - BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, + vnt_get_phy_field(priv, frame_size, current_rate, PK_TYPE_11A, &short_head->ab); /* Get Duration and TimeStampOff */ - short_head->duration = s_uGetDataDuration(pDevice, + short_head->duration = vnt_get_duration_le(priv, PK_TYPE_11A, false); short_head->time_stamp_off = - vnt_time_stamp_off(pDevice, wCurrentRate); + vnt_time_stamp_off(priv, current_rate); } else { - wCurrentRate = RATE_1M; - short_head->fifo_ctl |= FIFOCTL_11B; + current_rate = RATE_1M; + short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); /* Get SignalField,ServiceField,Length */ - BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, + vnt_get_phy_field(priv, frame_size, current_rate, PK_TYPE_11B, &short_head->ab); /* Get Duration and TimeStampOff */ - short_head->duration = s_uGetDataDuration(pDevice, + short_head->duration = vnt_get_duration_le(priv, PK_TYPE_11B, false); short_head->time_stamp_off = - vnt_time_stamp_off(pDevice, wCurrentRate); + vnt_time_stamp_off(priv, current_rate); } - /* Generate Beacon Header */ - pMACHeader = &pTX_Buffer->hdr; - - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - - pMACHeader->duration_id = 0; - pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize; + mgmt_hdr = &beacon_buffer->mgmt_hdr; + memcpy(mgmt_hdr, skb->data, skb->len); - pTX_Buffer->tx_byte_count = cpu_to_le16((u16)cbReqCount); - pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); - pTX_Buffer->byType = 0x01; + /* time stamp always 0 */ + mgmt_hdr->u.beacon.timestamp = 0; - pContext->skb = NULL; - pContext->type = CONTEXT_MGMT_PACKET; - pContext->buf_len = (u16)cbReqCount + 4; /* USB header */ + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr; + hdr->duration_id = 0; + hdr->seq_ctrl = cpu_to_le16(priv->seq_counter << 4); + } - PIPEnsSendBulkOut(pDevice,pContext); - return CMD_STATUS_PENDING; + priv->seq_counter++; + if (priv->seq_counter > 0x0fff) + priv->seq_counter = 0; -} + count = sizeof(struct vnt_tx_short_buf_head) + skb->len; -//TYPE_AC0DMA data tx -/* - * Description: - * Tx packet via AC0DMA(DMA1) - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * skb - Pointer to tx skb packet - * Out: - * void - * - * Return Value: NULL - */ + beacon_buffer->tx_byte_count = cpu_to_le16(count); + beacon_buffer->pkt_no = context->pkt_no; + beacon_buffer->type = 0x01; -int nsDMA_tx_packet(struct vnt_private *pDevice, struct sk_buff *skb) -{ - struct net_device_stats *pStats = &pDevice->stats; - struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; - struct vnt_tx_buffer *pTX_Buffer; - u32 BytesToWrite = 0, uHeaderLen = 0; - u32 uNodeIndex = 0; - u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - u16 wAID; - u8 byPktType; - int bNeedEncryption = false; - PSKeyItem pTransmitKey = NULL; - int ii; - int bTKIP_UseGTK = false; - int bNeedDeAuth = false; - u8 *pbyBSSID; - int bNodeExist = false; - struct vnt_usb_send_context *pContext; - bool fConvertedPacket; - u32 status; - u16 wKeepRate = pDevice->wCurrentRate; - int bTxeapol_key = false; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - - if (pDevice->uAssocCount == 0) { - dev_kfree_skb_irq(skb); - return 0; - } + context->type = CONTEXT_BEACON_PACKET; + context->buf_len = count + 4; /* USB header */ - if (is_multicast_ether_addr((u8 *)(skb->data))) { - uNodeIndex = 0; - bNodeExist = true; - if (pMgmt->sNodeDBTable[0].bPSEnable) { - - skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb); - pMgmt->sNodeDBTable[0].wEnQueueCnt++; - // set tx map - pMgmt->abyPSTxMap[0] |= byMask[0]; - return 0; - } - // multicast/broadcast data rate - - if (pDevice->byBBType != BB_TYPE_11A) - pDevice->wCurrentRate = RATE_2M; - else - pDevice->wCurrentRate = RATE_24M; - // long preamble type - pDevice->byPreambleType = PREAMBLE_SHORT; - - }else { - - if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data), &uNodeIndex)) { - - if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { - - skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb); - - pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++; - // set tx map - wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n", - (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]); - - return 0; - } - // AP rate decided from node - pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; - // tx preamble decided from node - - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) { - pDevice->byPreambleType = pDevice->byShortPreamble; - - }else { - pDevice->byPreambleType = PREAMBLE_LONG; - } - bNodeExist = true; - } - } + spin_lock_irqsave(&priv->lock, flags); - if (bNodeExist == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n"); - dev_kfree_skb_irq(skb); - return 0; - } - } + if (vnt_tx_context(priv, context) != STATUS_PENDING) + ieee80211_free_txskb(priv->hw, context->skb); - memcpy(&pDevice->sTxEthHeader, skb->data, ETH_HLEN); + spin_unlock_irqrestore(&priv->lock, flags); -//mike add:station mode check eapol-key challenge---> -{ - u8 Protocol_Version; //802.1x Authentication - u8 Packet_Type; //802.1x Authentication - u8 Descriptor_type; - u16 Key_info; - - Protocol_Version = skb->data[ETH_HLEN]; - Packet_Type = skb->data[ETH_HLEN+1]; - Descriptor_type = skb->data[ETH_HLEN+1+1+2]; - Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); - if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) { - /* 802.1x OR eapol-key challenge frame transfer */ - if (((Protocol_Version == 1) || (Protocol_Version == 2)) && - (Packet_Type == 3)) { - bTxeapol_key = true; - if(!(Key_info & BIT3) && //WPA or RSN group-key challenge - (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key - if(Descriptor_type==254) { - pDevice->fWPA_Authened = true; - PRINT_K("WPA "); - } - else { - pDevice->fWPA_Authened = true; - PRINT_K("WPA2(re-keying) "); - } - PRINT_K("Authentication completed!!\n"); - } - else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge - (Key_info & BIT8) && (Key_info & BIT9)) { - pDevice->fWPA_Authened = true; - PRINT_K("WPA2 Authentication completed!!\n"); - } - } - } + return 0; } -//mike add:station mode check eapol-key challenge<--- - - if (pDevice->bEncryptionEnable == true) { - bNeedEncryption = true; - // get Transmit key - do { - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - pbyBSSID = pDevice->abyBSSID; - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { - // get group key - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { - bTKIP_UseGTK = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n"); - break; - } - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n"); - break; - } - }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - /* TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 */ - pbyBSSID = pDevice->sTxEthHeader.h_dest; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n"); - for (ii = 0; ii< 6; ii++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n"); - - // get pairwise key - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) - break; - } - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode); - } - else - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode); - } else { - bTKIP_UseGTK = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n"); - } - } while(false); - } - - byPktType = (u8)pDevice->byPacketType; - - if (pDevice->bFixRate) { - if (pDevice->byBBType == BB_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) { - pDevice->wCurrentRate = RATE_11M; - } else { - pDevice->wCurrentRate = (u16)pDevice->uConnectionRate; - } - } else { - if ((pDevice->byBBType == BB_TYPE_11A) && - (pDevice->uConnectionRate <= RATE_6M)) { - pDevice->wCurrentRate = RATE_6M; - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = (u16)pDevice->uConnectionRate; - } - } - } - else { - if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) { - // Adhoc Tx rate decided from node DB - if (is_multicast_ether_addr(pDevice->sTxEthHeader.h_dest)) { - // Multicast use highest data rate - pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate; - // preamble type - pDevice->byPreambleType = pDevice->byShortPreamble; - } - else { - if (BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.h_dest[0]), &uNodeIndex)) { - pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) { - pDevice->byPreambleType = pDevice->byShortPreamble; - - } - else { - pDevice->byPreambleType = PREAMBLE_LONG; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d] Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate); - } - else { - if (pDevice->byBBType != BB_TYPE_11A) - pDevice->wCurrentRate = RATE_2M; - else - pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s - // abyCurrExtSuppRates[] - pDevice->byPreambleType = PREAMBLE_SHORT; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n"); - } - } - } - if (pDevice->op_mode == NL80211_IFTYPE_STATION) { - // Infra STA rate decided from AP Node, index = 0 - pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate; - } - } - - if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) { - if (pDevice->byBBType != BB_TYPE_11A) { - pDevice->wCurrentRate = RATE_1M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } else { - pDevice->wCurrentRate = RATE_6M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } - } - - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", - pDevice->wCurrentRate); - - if (wKeepRate != pDevice->wCurrentRate) { - bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL); - } - - if (pDevice->wCurrentRate <= RATE_11M) { - byPktType = PK_TYPE_11B; - } - - if (bNeedEncryption == true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.h_proto)); - if ((pDevice->sTxEthHeader.h_proto) == cpu_to_be16(ETH_P_PAE)) { - bNeedEncryption = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.h_proto)); - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - if (pTransmitKey == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n"); - } - else { - if (bTKIP_UseGTK == true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n"); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n", - pTransmitKey->dwKeyIndex); - bNeedEncryption = true; - } - } - } - } - else { - - if (pTransmitKey == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n"); - dev_kfree_skb_irq(skb); - pStats->tx_dropped++; - return STATUS_FAILURE; - } - } - } - - pContext = s_vGetFreeContext(pDevice); - if (!pContext) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n"); - dev_kfree_skb_irq(skb); - return STATUS_RESOURCES; - } - pTX_Buffer = (struct vnt_tx_buffer *)&pContext->data[0]; +int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif) +{ + struct sk_buff *beacon; - fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType, - pTX_Buffer, bNeedEncryption, - skb->len, &pDevice->sTxEthHeader, - (u8 *)skb->data, pTransmitKey, uNodeIndex, - pDevice->wCurrentRate, - &uHeaderLen, &BytesToWrite - ); + beacon = ieee80211_beacon_get(priv->hw, vif); + if (!beacon) + return -ENOMEM; - if (fConvertedPacket == false) { - pContext->in_use = false; - dev_kfree_skb_irq(skb); - return STATUS_FAILURE; + if (vnt_beacon_xmit(priv, beacon)) { + ieee80211_free_txskb(priv->hw, beacon); + return -ENODEV; } - if ( pDevice->bEnablePSMode == true ) { - if ( !pDevice->bPSModeTxBurst ) { - bScheduleCommand((void *) pDevice, - WLAN_CMD_MAC_DISPOWERSAVING, - NULL); - pDevice->bPSModeTxBurst = true; - } - } + return 0; +} - pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); - pTX_Buffer->tx_byte_count = cpu_to_le16((u16)BytesToWrite); +int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf) +{ + int ret; - pContext->skb = skb; - pContext->type = CONTEXT_DATA_PACKET; - pContext->buf_len = (u16)BytesToWrite + 4 ; /* USB header */ + vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); - s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F), - &pDevice->sTxEthHeader.h_dest[0], - (u16)(BytesToWrite-uHeaderLen), - pTX_Buffer->fifo_head.wFIFOCtl); + vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - status = PIPEnsSendBulkOut(pDevice,pContext); + vnt_mac_set_beacon_interval(priv, conf->beacon_int); - if (bNeedDeAuth == true) { - u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE; + vnt_clear_current_tsf(priv); - bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason); - } + vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - if (status != STATUS_PENDING) { - pContext->in_use = false; - dev_kfree_skb_irq(skb); - return STATUS_FAILURE; - } + vnt_reset_next_tbtt(priv, conf->beacon_int); + ret = vnt_beacon_make(priv, vif); - return 0; + return ret; } |