1463 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.4 * All rights reserved.5 *6 * Purpose: handle WMAC/802.3/802.11 rx & tx functions7 *8 * Author: Lyndon Chen9 *10 * Date: May 20, 200311 *12 * Functions:13 * s_vGenerateTxParameter - Generate tx dma required parameter.14 * vGenerateMACHeader - Translate 802.3 to 802.11 header15 * cbGetFragCount - Calculate fragment number count16 * csBeacon_xmit - beacon tx function17 * csMgmt_xmit - management tx function18 * s_cbFillTxBufHead - fulfill tx dma buffer header19 * s_uGetDataDuration - get tx data required duration20 * s_uFillDataHead- fulfill tx data duration header21 * s_uGetRTSCTSDuration- get rtx/cts required duration22 * get_rtscts_time- get rts/cts reserved time23 * s_uGetTxRsvTime- get frame reserved time24 * s_vFillCTSHead- fulfill CTS ctl header25 * s_vFillFragParameter- Set fragment ctl parameter.26 * s_vFillRTSHead- fulfill RTS ctl header27 * s_vFillTxKey- fulfill tx encrypt key28 * s_vSWencryption- Software encrypt header29 * vDMA0_tx_80211- tx 802.11 frame via dma030 * vGenerateFIFOHeader- Generate tx FIFO ctl header31 *32 * Revision History:33 *34 */35 36#include "device.h"37#include "rxtx.h"38#include "card.h"39#include "mac.h"40#include "baseband.h"41#include "rf.h"42 43/*--------------------- Static Definitions -------------------------*/44 45/*--------------------- Static Classes ----------------------------*/46 47/*--------------------- Static Variables --------------------------*/48 49/*--------------------- Static Functions --------------------------*/50 51/*--------------------- Static Definitions -------------------------*/52/* if packet size < 256 -> in-direct send53 * vpacket size >= 256 -> direct send54 */55#define CRITICAL_PACKET_LEN 25656 57static const unsigned short time_stamp_off[2][MAX_RATE] = {58 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */59 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */60};61 62static const unsigned short fb_opt0[2][5] = {63 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */64 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */65};66 67static const unsigned short fb_opt1[2][5] = {68 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */69 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */70};71 72#define RTSDUR_BB 073#define RTSDUR_BA 174#define RTSDUR_AA 275#define CTSDUR_BA 376#define RTSDUR_BA_F0 477#define RTSDUR_AA_F0 578#define RTSDUR_BA_F1 679#define RTSDUR_AA_F1 780#define CTSDUR_BA_F0 881#define CTSDUR_BA_F1 982#define DATADUR_B 1083#define DATADUR_A 1184#define DATADUR_A_F0 1285#define DATADUR_A_F1 1386 87/*--------------------- Static Functions --------------------------*/88static89void90s_vFillRTSHead(91 struct vnt_private *pDevice,92 unsigned char byPktType,93 void *pvRTS,94 unsigned int cbFrameLength,95 bool bNeedAck,96 bool bDisCRC,97 struct ieee80211_hdr *hdr,98 unsigned short wCurrentRate,99 unsigned char byFBOption100);101 102static103void104s_vGenerateTxParameter(105 struct vnt_private *pDevice,106 unsigned char byPktType,107 struct vnt_tx_fifo_head *,108 void *pvRrvTime,109 void *pvRTS,110 void *pvCTS,111 unsigned int cbFrameSize,112 bool bNeedACK,113 unsigned int uDMAIdx,114 void *psEthHeader,115 unsigned short wCurrentRate116);117 118static unsigned int119s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,120 unsigned char *pbyTxBufferAddr,121 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,122 unsigned int uNodeIndex);123 124static125__le16126s_uFillDataHead(127 struct vnt_private *pDevice,128 unsigned char byPktType,129 void *pTxDataHead,130 unsigned int cbFrameLength,131 unsigned int uDMAIdx,132 bool bNeedAck,133 unsigned int uFragIdx,134 unsigned int cbLastFragmentSize,135 unsigned int uMACfragNum,136 unsigned char byFBOption,137 unsigned short wCurrentRate,138 bool is_pspoll139);140 141/*--------------------- Export Variables --------------------------*/142 143static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)144{145 return cpu_to_le16(time_stamp_off[priv->preamble_type % 2]146 [rate % MAX_RATE]);147}148 149/* byPktType : PK_TYPE_11A 0150 * PK_TYPE_11B 1151 * PK_TYPE_11GB 2152 * PK_TYPE_11GA 3153 */154static155unsigned int156s_uGetTxRsvTime(157 struct vnt_private *pDevice,158 unsigned char byPktType,159 unsigned int cbFrameLength,160 unsigned short wRate,161 bool bNeedAck162)163{164 unsigned int uDataTime, uAckTime;165 166 uDataTime = bb_get_frame_time(pDevice->preamble_type, byPktType, cbFrameLength, wRate);167 168 if (!bNeedAck)169 return uDataTime;170 171 /*172 * CCK mode - 11b173 * OFDM mode - 11g 2.4G & 11a 5G174 */175 uAckTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14,176 byPktType == PK_TYPE_11B ?177 pDevice->byTopCCKBasicRate :178 pDevice->byTopOFDMBasicRate);179 180 return uDataTime + pDevice->uSIFS + uAckTime;181}182 183static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,184 u32 frame_length, u16 rate, bool need_ack)185{186 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,187 frame_length, rate, need_ack));188}189 190/* byFreqType: 0=>5GHZ 1=>2.4GHZ */191static __le16 get_rtscts_time(struct vnt_private *priv,192 unsigned char rts_rsvtype,193 unsigned char pkt_type,194 unsigned int frame_length,195 unsigned short current_rate)196{197 unsigned int rrv_time = 0;198 unsigned int rts_time = 0;199 unsigned int cts_time = 0;200 unsigned int ack_time = 0;201 unsigned int data_time = 0;202 203 data_time = bb_get_frame_time(priv->preamble_type, pkt_type, frame_length, current_rate);204 if (rts_rsvtype == 0) { /* RTSTxRrvTime_bb */205 rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);206 ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);207 cts_time = ack_time;208 } else if (rts_rsvtype == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */209 rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);210 cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);211 ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);212 } else if (rts_rsvtype == 2) { /* RTSTxRrvTime_aa */213 rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopOFDMBasicRate);214 ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);215 cts_time = ack_time;216 } else if (rts_rsvtype == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */217 cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);218 ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);219 rrv_time = cts_time + ack_time + data_time + 2 * priv->uSIFS;220 return cpu_to_le16((u16)rrv_time);221 }222 223 /* RTSRrvTime */224 rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS;225 return cpu_to_le16((u16)rrv_time);226}227 228/* byFreqType 0: 5GHz, 1:2.4Ghz */229static230unsigned int231s_uGetDataDuration(232 struct vnt_private *pDevice,233 unsigned char byDurType,234 unsigned int cbFrameLength,235 unsigned char byPktType,236 unsigned short wRate,237 bool bNeedAck,238 unsigned int uFragIdx,239 unsigned int cbLastFragmentSize,240 unsigned int uMACfragNum,241 unsigned char byFBOption242)243{244 bool bLastFrag = false;245 unsigned int uAckTime = 0, uNextPktTime = 0, len;246 247 if (uFragIdx == (uMACfragNum - 1))248 bLastFrag = true;249 250 if (uFragIdx == (uMACfragNum - 2))251 len = cbLastFragmentSize;252 else253 len = cbFrameLength;254 255 switch (byDurType) {256 case DATADUR_B: /* DATADUR_B */257 if (bNeedAck) {258 uAckTime = bb_get_frame_time(pDevice->preamble_type,259 byPktType, 14,260 pDevice->byTopCCKBasicRate);261 }262 /* Non Frag or Last Frag */263 if ((uMACfragNum == 1) || bLastFrag) {264 if (!bNeedAck)265 return 0;266 } else {267 /* First Frag or Mid Frag */268 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,269 len, wRate, bNeedAck);270 }271 272 return pDevice->uSIFS + uAckTime + uNextPktTime;273 274 case DATADUR_A: /* DATADUR_A */275 if (bNeedAck) {276 uAckTime = bb_get_frame_time(pDevice->preamble_type,277 byPktType, 14,278 pDevice->byTopOFDMBasicRate);279 }280 /* Non Frag or Last Frag */281 if ((uMACfragNum == 1) || bLastFrag) {282 if (!bNeedAck)283 return 0;284 } else {285 /* First Frag or Mid Frag */286 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,287 len, wRate, bNeedAck);288 }289 290 return pDevice->uSIFS + uAckTime + uNextPktTime;291 292 case DATADUR_A_F0: /* DATADUR_A_F0 */293 case DATADUR_A_F1: /* DATADUR_A_F1 */294 if (bNeedAck) {295 uAckTime = bb_get_frame_time(pDevice->preamble_type,296 byPktType, 14,297 pDevice->byTopOFDMBasicRate);298 }299 /* Non Frag or Last Frag */300 if ((uMACfragNum == 1) || bLastFrag) {301 if (!bNeedAck)302 return 0;303 } else {304 /* First Frag or Mid Frag */305 if (wRate < RATE_18M)306 wRate = RATE_18M;307 else if (wRate > RATE_54M)308 wRate = RATE_54M;309 310 wRate -= RATE_18M;311 312 if (byFBOption == AUTO_FB_0)313 wRate = fb_opt0[FB_RATE0][wRate];314 else315 wRate = fb_opt1[FB_RATE0][wRate];316 317 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,318 len, wRate, bNeedAck);319 }320 321 return pDevice->uSIFS + uAckTime + uNextPktTime;322 323 default:324 break;325 }326 327 return 0;328}329 330/* byFreqType: 0=>5GHZ 1=>2.4GHZ */331static332__le16333s_uGetRTSCTSDuration(334 struct vnt_private *pDevice,335 unsigned char byDurType,336 unsigned int cbFrameLength,337 unsigned char byPktType,338 unsigned short wRate,339 bool bNeedAck,340 unsigned char byFBOption341)342{343 unsigned int uCTSTime = 0, uDurTime = 0;344 345 switch (byDurType) {346 case RTSDUR_BB: /* RTSDuration_bb */347 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);348 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);349 break;350 351 case RTSDUR_BA: /* RTSDuration_ba */352 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);353 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);354 break;355 356 case RTSDUR_AA: /* RTSDuration_aa */357 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);358 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);359 break;360 361 case CTSDUR_BA: /* CTSDuration_ba */362 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);363 break;364 365 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */366 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);367 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))368 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);369 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))370 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);371 372 break;373 374 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */375 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);376 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))377 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);378 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))379 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);380 381 break;382 383 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */384 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);385 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))386 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);387 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))388 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);389 390 break;391 392 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */393 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);394 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))395 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);396 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))397 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);398 399 break;400 401 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */402 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))403 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);404 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))405 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);406 407 break;408 409 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */410 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))411 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);412 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))413 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);414 415 break;416 417 default:418 break;419 }420 421 return cpu_to_le16((u16)uDurTime);422}423 424static425__le16426s_uFillDataHead(427 struct vnt_private *pDevice,428 unsigned char byPktType,429 void *pTxDataHead,430 unsigned int cbFrameLength,431 unsigned int uDMAIdx,432 bool bNeedAck,433 unsigned int uFragIdx,434 unsigned int cbLastFragmentSize,435 unsigned int uMACfragNum,436 unsigned char byFBOption,437 unsigned short wCurrentRate,438 bool is_pspoll439)440{441 struct vnt_tx_datahead_ab *buf = pTxDataHead;442 443 if (!pTxDataHead)444 return 0;445 446 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {447 /* Auto Fallback */448 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;449 450 if (byFBOption == AUTO_FB_NONE) {451 struct vnt_tx_datahead_g *buf = pTxDataHead;452 /* Get SignalField, ServiceField & Length */453 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,454 byPktType, &buf->a);455 456 vnt_get_phy_field(pDevice, cbFrameLength,457 pDevice->byTopCCKBasicRate,458 PK_TYPE_11B, &buf->b);459 460 if (is_pspoll) {461 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));462 463 buf->duration_a = dur;464 buf->duration_b = dur;465 } else {466 /* Get Duration and TimeStamp */467 buf->duration_a =468 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,469 byPktType, wCurrentRate, bNeedAck, uFragIdx,470 cbLastFragmentSize, uMACfragNum,471 byFBOption));472 buf->duration_b =473 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,474 PK_TYPE_11B, pDevice->byTopCCKBasicRate,475 bNeedAck, uFragIdx, cbLastFragmentSize,476 uMACfragNum, byFBOption));477 }478 479 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);480 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);481 482 return buf->duration_a;483 }484 485 /* Get SignalField, ServiceField & Length */486 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,487 byPktType, &buf->a);488 489 vnt_get_phy_field(pDevice, cbFrameLength,490 pDevice->byTopCCKBasicRate,491 PK_TYPE_11B, &buf->b);492 /* Get Duration and TimeStamp */493 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,494 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));495 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,496 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));497 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,498 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));499 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,500 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));501 502 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);503 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);504 505 return buf->duration_a;506 /* if (byFBOption == AUTO_FB_NONE) */507 } else if (byPktType == PK_TYPE_11A) {508 struct vnt_tx_datahead_ab *buf = pTxDataHead;509 510 if (byFBOption != AUTO_FB_NONE) {511 /* Auto Fallback */512 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;513 /* Get SignalField, ServiceField & Length */514 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,515 byPktType, &buf->a);516 517 /* Get Duration and TimeStampOff */518 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,519 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));520 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,521 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));522 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,523 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));524 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);525 return buf->duration;526 }527 528 /* Get SignalField, ServiceField & Length */529 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,530 byPktType, &buf->ab);531 532 if (is_pspoll) {533 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));534 535 buf->duration = dur;536 } else {537 /* Get Duration and TimeStampOff */538 buf->duration =539 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,540 wCurrentRate, bNeedAck, uFragIdx,541 cbLastFragmentSize, uMACfragNum,542 byFBOption));543 }544 545 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);546 return buf->duration;547 }548 549 /* Get SignalField, ServiceField & Length */550 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,551 byPktType, &buf->ab);552 553 if (is_pspoll) {554 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));555 556 buf->duration = dur;557 } else {558 /* Get Duration and TimeStampOff */559 buf->duration =560 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,561 wCurrentRate, bNeedAck, uFragIdx,562 cbLastFragmentSize, uMACfragNum,563 byFBOption));564 }565 566 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);567 return buf->duration;568}569 570static571void572s_vFillRTSHead(573 struct vnt_private *pDevice,574 unsigned char byPktType,575 void *pvRTS,576 unsigned int cbFrameLength,577 bool bNeedAck,578 bool bDisCRC,579 struct ieee80211_hdr *hdr,580 unsigned short wCurrentRate,581 unsigned char byFBOption582)583{584 unsigned int uRTSFrameLen = 20;585 586 if (!pvRTS)587 return;588 589 if (bDisCRC) {590 /* When CRCDIS bit is on, H/W forgot to generate FCS for591 * RTS frame, in this case we need to decrease its length by 4.592 */593 uRTSFrameLen -= 4;594 }595 596 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,597 * so we don't need to take them into account.598 * Otherwise, we need to modify codes for them.599 */600 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {601 if (byFBOption == AUTO_FB_NONE) {602 struct vnt_rts_g *buf = pvRTS;603 /* Get SignalField, ServiceField & Length */604 vnt_get_phy_field(pDevice, uRTSFrameLen,605 pDevice->byTopCCKBasicRate,606 PK_TYPE_11B, &buf->b);607 608 vnt_get_phy_field(pDevice, uRTSFrameLen,609 pDevice->byTopOFDMBasicRate,610 byPktType, &buf->a);611 /* Get Duration */612 buf->duration_bb =613 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,614 cbFrameLength, PK_TYPE_11B,615 pDevice->byTopCCKBasicRate,616 bNeedAck, byFBOption);617 buf->duration_aa =618 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,619 cbFrameLength, byPktType,620 wCurrentRate, bNeedAck,621 byFBOption);622 buf->duration_ba =623 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,624 cbFrameLength, byPktType,625 wCurrentRate, bNeedAck,626 byFBOption);627 628 buf->data.duration = buf->duration_aa;629 /* Get RTS Frame body */630 buf->data.frame_control =631 cpu_to_le16(IEEE80211_FTYPE_CTL |632 IEEE80211_STYPE_RTS);633 634 ether_addr_copy(buf->data.ra, hdr->addr1);635 ether_addr_copy(buf->data.ta, hdr->addr2);636 } else {637 struct vnt_rts_g_fb *buf = pvRTS;638 /* Get SignalField, ServiceField & Length */639 vnt_get_phy_field(pDevice, uRTSFrameLen,640 pDevice->byTopCCKBasicRate,641 PK_TYPE_11B, &buf->b);642 643 vnt_get_phy_field(pDevice, uRTSFrameLen,644 pDevice->byTopOFDMBasicRate,645 byPktType, &buf->a);646 /* Get Duration */647 buf->duration_bb =648 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,649 cbFrameLength, PK_TYPE_11B,650 pDevice->byTopCCKBasicRate,651 bNeedAck, byFBOption);652 buf->duration_aa =653 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,654 cbFrameLength, byPktType,655 wCurrentRate, bNeedAck,656 byFBOption);657 buf->duration_ba =658 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,659 cbFrameLength, byPktType,660 wCurrentRate, bNeedAck,661 byFBOption);662 buf->rts_duration_ba_f0 =663 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,664 cbFrameLength, byPktType,665 wCurrentRate, bNeedAck,666 byFBOption);667 buf->rts_duration_aa_f0 =668 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,669 cbFrameLength, byPktType,670 wCurrentRate, bNeedAck,671 byFBOption);672 buf->rts_duration_ba_f1 =673 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,674 cbFrameLength, byPktType,675 wCurrentRate, bNeedAck,676 byFBOption);677 buf->rts_duration_aa_f1 =678 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,679 cbFrameLength, byPktType,680 wCurrentRate, bNeedAck,681 byFBOption);682 buf->data.duration = buf->duration_aa;683 /* Get RTS Frame body */684 buf->data.frame_control =685 cpu_to_le16(IEEE80211_FTYPE_CTL |686 IEEE80211_STYPE_RTS);687 688 ether_addr_copy(buf->data.ra, hdr->addr1);689 ether_addr_copy(buf->data.ta, hdr->addr2);690 } /* if (byFBOption == AUTO_FB_NONE) */691 } else if (byPktType == PK_TYPE_11A) {692 if (byFBOption == AUTO_FB_NONE) {693 struct vnt_rts_ab *buf = pvRTS;694 /* Get SignalField, ServiceField & Length */695 vnt_get_phy_field(pDevice, uRTSFrameLen,696 pDevice->byTopOFDMBasicRate,697 byPktType, &buf->ab);698 /* Get Duration */699 buf->duration =700 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,701 cbFrameLength, byPktType,702 wCurrentRate, bNeedAck,703 byFBOption);704 buf->data.duration = buf->duration;705 /* Get RTS Frame body */706 buf->data.frame_control =707 cpu_to_le16(IEEE80211_FTYPE_CTL |708 IEEE80211_STYPE_RTS);709 710 ether_addr_copy(buf->data.ra, hdr->addr1);711 ether_addr_copy(buf->data.ta, hdr->addr2);712 } else {713 struct vnt_rts_a_fb *buf = pvRTS;714 /* Get SignalField, ServiceField & Length */715 vnt_get_phy_field(pDevice, uRTSFrameLen,716 pDevice->byTopOFDMBasicRate,717 byPktType, &buf->a);718 /* Get Duration */719 buf->duration =720 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,721 cbFrameLength, byPktType,722 wCurrentRate, bNeedAck,723 byFBOption);724 buf->rts_duration_f0 =725 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,726 cbFrameLength, byPktType,727 wCurrentRate, bNeedAck,728 byFBOption);729 buf->rts_duration_f1 =730 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,731 cbFrameLength, byPktType,732 wCurrentRate, bNeedAck,733 byFBOption);734 buf->data.duration = buf->duration;735 /* Get RTS Frame body */736 buf->data.frame_control =737 cpu_to_le16(IEEE80211_FTYPE_CTL |738 IEEE80211_STYPE_RTS);739 740 ether_addr_copy(buf->data.ra, hdr->addr1);741 ether_addr_copy(buf->data.ta, hdr->addr2);742 }743 } else if (byPktType == PK_TYPE_11B) {744 struct vnt_rts_ab *buf = pvRTS;745 /* Get SignalField, ServiceField & Length */746 vnt_get_phy_field(pDevice, uRTSFrameLen,747 pDevice->byTopCCKBasicRate,748 PK_TYPE_11B, &buf->ab);749 /* Get Duration */750 buf->duration =751 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,752 byPktType, wCurrentRate, bNeedAck,753 byFBOption);754 755 buf->data.duration = buf->duration;756 /* Get RTS Frame body */757 buf->data.frame_control =758 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);759 760 ether_addr_copy(buf->data.ra, hdr->addr1);761 ether_addr_copy(buf->data.ta, hdr->addr2);762 }763}764 765static766void767s_vFillCTSHead(768 struct vnt_private *pDevice,769 unsigned int uDMAIdx,770 unsigned char byPktType,771 void *pvCTS,772 unsigned int cbFrameLength,773 bool bNeedAck,774 bool bDisCRC,775 unsigned short wCurrentRate,776 unsigned char byFBOption777)778{779 unsigned int uCTSFrameLen = 14;780 781 if (!pvCTS)782 return;783 784 if (bDisCRC) {785 /* When CRCDIS bit is on, H/W forgot to generate FCS for786 * CTS frame, in this case we need to decrease its length by 4.787 */788 uCTSFrameLen -= 4;789 }790 791 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {792 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {793 /* Auto Fall back */794 struct vnt_cts_fb *buf = pvCTS;795 /* Get SignalField, ServiceField & Length */796 vnt_get_phy_field(pDevice, uCTSFrameLen,797 pDevice->byTopCCKBasicRate,798 PK_TYPE_11B, &buf->b);799 800 buf->duration_ba =801 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,802 cbFrameLength, byPktType,803 wCurrentRate, bNeedAck,804 byFBOption);805 806 /* Get CTSDuration_ba_f0 */807 buf->cts_duration_ba_f0 =808 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,809 cbFrameLength, byPktType,810 wCurrentRate, bNeedAck,811 byFBOption);812 813 /* Get CTSDuration_ba_f1 */814 buf->cts_duration_ba_f1 =815 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,816 cbFrameLength, byPktType,817 wCurrentRate, bNeedAck,818 byFBOption);819 820 /* Get CTS Frame body */821 buf->data.duration = buf->duration_ba;822 823 buf->data.frame_control =824 cpu_to_le16(IEEE80211_FTYPE_CTL |825 IEEE80211_STYPE_CTS);826 827 buf->reserved2 = 0x0;828 829 ether_addr_copy(buf->data.ra,830 pDevice->abyCurrentNetAddr);831 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */832 struct vnt_cts *buf = pvCTS;833 /* Get SignalField, ServiceField & Length */834 vnt_get_phy_field(pDevice, uCTSFrameLen,835 pDevice->byTopCCKBasicRate,836 PK_TYPE_11B, &buf->b);837 838 /* Get CTSDuration_ba */839 buf->duration_ba =840 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,841 cbFrameLength, byPktType,842 wCurrentRate, bNeedAck,843 byFBOption);844 845 /* Get CTS Frame body */846 buf->data.duration = buf->duration_ba;847 848 buf->data.frame_control =849 cpu_to_le16(IEEE80211_FTYPE_CTL |850 IEEE80211_STYPE_CTS);851 852 buf->reserved2 = 0x0;853 ether_addr_copy(buf->data.ra,854 pDevice->abyCurrentNetAddr);855 }856 }857}858 859/*860 *861 * Description:862 * Generate FIFO control for MAC & Baseband controller863 *864 * Parameters:865 * In:866 * pDevice - Pointer to adapter867 * pTxDataHead - Transmit Data Buffer868 * pTxBufHead - pTxBufHead869 * pvRrvTime - pvRrvTime870 * pvRTS - RTS Buffer871 * pCTS - CTS Buffer872 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)873 * bNeedACK - If need ACK874 * uDescIdx - Desc Index875 * Out:876 * none877 *878 * Return Value: none879 *880 -881 * unsigned int cbFrameSize, Hdr+Payload+FCS882 */883static884void885s_vGenerateTxParameter(886 struct vnt_private *pDevice,887 unsigned char byPktType,888 struct vnt_tx_fifo_head *tx_buffer_head,889 void *pvRrvTime,890 void *pvRTS,891 void *pvCTS,892 unsigned int cbFrameSize,893 bool bNeedACK,894 unsigned int uDMAIdx,895 void *psEthHeader,896 unsigned short wCurrentRate897)898{899 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);900 bool bDisCRC = false;901 unsigned char byFBOption = AUTO_FB_NONE;902 903 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);904 905 if (fifo_ctl & FIFOCTL_CRCDIS)906 bDisCRC = true;907 908 if (fifo_ctl & FIFOCTL_AUTO_FB_0)909 byFBOption = AUTO_FB_0;910 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)911 byFBOption = AUTO_FB_1;912 913 if (!pvRrvTime)914 return;915 916 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {917 if (pvRTS) { /* RTS_need */918 /* Fill RsvTime */919 struct vnt_rrv_time_rts *buf = pvRrvTime;920 921 buf->rts_rrv_time_aa = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);922 buf->rts_rrv_time_ba = get_rtscts_time(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);923 buf->rts_rrv_time_bb = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);924 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);925 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);926 927 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);928 } else {/* RTS_needless, PCF mode */929 struct vnt_rrv_time_cts *buf = pvRrvTime;930 931 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);932 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);933 buf->cts_rrv_time_ba = get_rtscts_time(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);934 935 /* Fill CTS */936 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);937 }938 } else if (byPktType == PK_TYPE_11A) {939 if (pvRTS) {/* RTS_need, non PCF mode */940 struct vnt_rrv_time_ab *buf = pvRrvTime;941 942 buf->rts_rrv_time = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);943 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);944 945 /* Fill RTS */946 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);947 } else if (!pvRTS) {/* RTS_needless, non PCF mode */948 struct vnt_rrv_time_ab *buf = pvRrvTime;949 950 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);951 }952 } else if (byPktType == PK_TYPE_11B) {953 if (pvRTS) {/* RTS_need, non PCF mode */954 struct vnt_rrv_time_ab *buf = pvRrvTime;955 956 buf->rts_rrv_time = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);957 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);958 959 /* Fill RTS */960 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);961 } else { /* RTS_needless, non PCF mode */962 struct vnt_rrv_time_ab *buf = pvRrvTime;963 964 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);965 }966 }967}968 969static unsigned int970s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,971 unsigned char *pbyTxBufferAddr,972 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,973 unsigned int is_pspoll)974{975 struct vnt_td_info *td_info = pHeadTD->td_info;976 struct sk_buff *skb = td_info->skb;977 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);978 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;979 struct vnt_tx_fifo_head *tx_buffer_head =980 (struct vnt_tx_fifo_head *)td_info->buf;981 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);982 unsigned int cbFrameSize;983 __le16 uDuration;984 unsigned char *pbyBuffer;985 unsigned int uLength = 0;986 unsigned int cbMICHDR = 0;987 unsigned int uMACfragNum = 1;988 unsigned int uPadding = 0;989 unsigned int cbReqCount = 0;990 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);991 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);992 struct vnt_tx_desc *ptdCurr;993 unsigned int cbHeaderLength = 0;994 void *pvRrvTime = NULL;995 struct vnt_mic_hdr *pMICHDR = NULL;996 void *pvRTS = NULL;997 void *pvCTS = NULL;998 void *pvTxDataHd = NULL;999 unsigned short wTxBufSize; /* FFinfo size */1000 unsigned char byFBOption = AUTO_FB_NONE;1001 1002 cbFrameSize = skb->len + 4;1003 1004 if (info->control.hw_key) {1005 switch (info->control.hw_key->cipher) {1006 case WLAN_CIPHER_SUITE_CCMP:1007 cbMICHDR = sizeof(struct vnt_mic_hdr);1008 break;1009 default:1010 break;1011 }1012 1013 cbFrameSize += info->control.hw_key->icv_len;1014 1015 if (pDevice->local_id > REV_ID_VT3253_A1) {1016 /* MAC Header should be padding 0 to DW alignment. */1017 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);1018 uPadding %= 4;1019 }1020 }1021 1022 /*1023 * Use for AUTO FALL BACK1024 */1025 if (fifo_ctl & FIFOCTL_AUTO_FB_0)1026 byFBOption = AUTO_FB_0;1027 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)1028 byFBOption = AUTO_FB_1;1029 1030 /* Set RrvTime/RTS/CTS Buffer */1031 wTxBufSize = sizeof(struct vnt_tx_fifo_head);1032 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */1033 1034 if (byFBOption == AUTO_FB_NONE) {1035 if (bRTS) {/* RTS_need */1036 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1037 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));1038 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);1039 pvCTS = NULL;1040 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +1041 cbMICHDR + sizeof(struct vnt_rts_g));1042 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +1043 cbMICHDR + sizeof(struct vnt_rts_g) +1044 sizeof(struct vnt_tx_datahead_g);1045 } else { /* RTS_needless */1046 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1047 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));1048 pvRTS = NULL;1049 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);1050 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +1051 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));1052 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +1053 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);1054 }1055 } else {1056 /* Auto Fall Back */1057 if (bRTS) {/* RTS_need */1058 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1059 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));1060 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);1061 pvCTS = NULL;1062 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +1063 cbMICHDR + sizeof(struct vnt_rts_g_fb));1064 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +1065 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);1066 } else { /* RTS_needless */1067 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1068 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));1069 pvRTS = NULL;1070 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);1071 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +1072 cbMICHDR + sizeof(struct vnt_cts_fb));1073 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +1074 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);1075 }1076 } /* Auto Fall Back */1077 } else {/* 802.11a/b packet */1078 1079 if (byFBOption == AUTO_FB_NONE) {1080 if (bRTS) {1081 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1082 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));1083 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);1084 pvCTS = NULL;1085 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +1086 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));1087 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +1088 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);1089 } else { /* RTS_needless, need MICHDR */1090 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1091 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));1092 pvRTS = NULL;1093 pvCTS = NULL;1094 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);1095 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +1096 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);1097 }1098 } else {1099 /* Auto Fall Back */1100 if (bRTS) { /* RTS_need */1101 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1102 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));1103 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);1104 pvCTS = NULL;1105 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +1106 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));1107 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +1108 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);1109 } else { /* RTS_needless */1110 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1111 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));1112 pvRTS = NULL;1113 pvCTS = NULL;1114 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);1115 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +1116 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);1117 }1118 } /* Auto Fall Back */1119 }1120 1121 td_info->mic_hdr = pMICHDR;1122 1123 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));1124 1125 /* Fill FIFO,RrvTime,RTS,and CTS */1126 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,1127 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);1128 /* Fill DataHead */1129 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,1130 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);1131 1132 hdr->duration_id = uDuration;1133 1134 cbReqCount = cbHeaderLength + uPadding + skb->len;1135 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;1136 uLength = cbHeaderLength + uPadding;1137 1138 /* Copy the Packet into a tx Buffer */1139 memcpy((pbyBuffer + uLength), skb->data, skb->len);1140 1141 ptdCurr = pHeadTD;1142 1143 ptdCurr->td_info->req_count = (u16)cbReqCount;1144 1145 return cbHeaderLength;1146}1147 1148static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,1149 struct ieee80211_key_conf *tx_key,1150 struct sk_buff *skb, u16 payload_len,1151 struct vnt_mic_hdr *mic_hdr)1152{1153 u64 pn64;1154 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));1155 1156 /* strip header and icv len from payload */1157 payload_len -= ieee80211_get_hdrlen_from_skb(skb);1158 payload_len -= tx_key->icv_len;1159 1160 switch (tx_key->cipher) {1161 case WLAN_CIPHER_SUITE_WEP40:1162 case WLAN_CIPHER_SUITE_WEP104:1163 memcpy(key_buffer, iv, 3);1164 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);1165 1166 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {1167 memcpy(key_buffer + 8, iv, 3);1168 memcpy(key_buffer + 11,1169 tx_key->key, WLAN_KEY_LEN_WEP40);1170 }1171 1172 break;1173 case WLAN_CIPHER_SUITE_TKIP:1174 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);1175 1176 break;1177 case WLAN_CIPHER_SUITE_CCMP:1178 1179 if (!mic_hdr)1180 return;1181 1182 mic_hdr->id = 0x59;1183 mic_hdr->payload_len = cpu_to_be16(payload_len);1184 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);1185 1186 pn64 = atomic64_read(&tx_key->tx_pn);1187 mic_hdr->ccmp_pn[5] = pn64;1188 mic_hdr->ccmp_pn[4] = pn64 >> 8;1189 mic_hdr->ccmp_pn[3] = pn64 >> 16;1190 mic_hdr->ccmp_pn[2] = pn64 >> 24;1191 mic_hdr->ccmp_pn[1] = pn64 >> 32;1192 mic_hdr->ccmp_pn[0] = pn64 >> 40;1193 1194 if (ieee80211_has_a4(hdr->frame_control))1195 mic_hdr->hlen = cpu_to_be16(28);1196 else1197 mic_hdr->hlen = cpu_to_be16(22);1198 1199 ether_addr_copy(mic_hdr->addr1, hdr->addr1);1200 ether_addr_copy(mic_hdr->addr2, hdr->addr2);1201 ether_addr_copy(mic_hdr->addr3, hdr->addr3);1202 1203 mic_hdr->frame_control = cpu_to_le16(1204 le16_to_cpu(hdr->frame_control) & 0xc78f);1205 mic_hdr->seq_ctrl = cpu_to_le16(1206 le16_to_cpu(hdr->seq_ctrl) & 0xf);1207 1208 if (ieee80211_has_a4(hdr->frame_control))1209 ether_addr_copy(mic_hdr->addr4, hdr->addr4);1210 1211 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);1212 1213 break;1214 default:1215 break;1216 }1217}1218 1219int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,1220 struct vnt_tx_desc *head_td, struct sk_buff *skb)1221{1222 struct vnt_td_info *td_info = head_td->td_info;1223 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);1224 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];1225 struct ieee80211_rate *rate;1226 struct ieee80211_key_conf *tx_key;1227 struct ieee80211_hdr *hdr;1228 struct vnt_tx_fifo_head *tx_buffer_head =1229 (struct vnt_tx_fifo_head *)td_info->buf;1230 u16 tx_body_size = skb->len, current_rate;1231 u8 pkt_type;1232 bool is_pspoll = false;1233 1234 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));1235 1236 hdr = (struct ieee80211_hdr *)(skb->data);1237 1238 rate = ieee80211_get_tx_rate(priv->hw, info);1239 1240 current_rate = rate->hw_value;1241 if (priv->wCurrentRate != current_rate &&1242 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {1243 priv->wCurrentRate = current_rate;1244 1245 RFbSetPower(priv, priv->wCurrentRate,1246 priv->hw->conf.chandef.chan->hw_value);1247 }1248 1249 if (current_rate > RATE_11M) {1250 if (info->band == NL80211_BAND_5GHZ) {1251 pkt_type = PK_TYPE_11A;1252 } else {1253 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)1254 pkt_type = PK_TYPE_11GB;1255 else1256 pkt_type = PK_TYPE_11GA;1257 }1258 } else {1259 pkt_type = PK_TYPE_11B;1260 }1261 1262 /*Set fifo controls */1263 if (pkt_type == PK_TYPE_11A)1264 tx_buffer_head->fifo_ctl = 0;1265 else if (pkt_type == PK_TYPE_11B)1266 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);1267 else if (pkt_type == PK_TYPE_11GB)1268 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);1269 else if (pkt_type == PK_TYPE_11GA)1270 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);1271 1272 /* generate interrupt */1273 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);1274 1275 if (!ieee80211_is_data(hdr->frame_control)) {1276 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);1277 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);1278 tx_buffer_head->time_stamp =1279 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);1280 } else {1281 tx_buffer_head->time_stamp =1282 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);1283 }1284 1285 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))1286 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);1287 1288 if (ieee80211_has_retry(hdr->frame_control))1289 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);1290 1291 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)1292 priv->preamble_type = PREAMBLE_SHORT;1293 else1294 priv->preamble_type = PREAMBLE_LONG;1295 1296 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)1297 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);1298 1299 if (ieee80211_has_a4(hdr->frame_control)) {1300 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);1301 priv->bLongHeader = true;1302 }1303 1304 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)1305 is_pspoll = true;1306 1307 tx_buffer_head->frag_ctl =1308 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);1309 1310 if (info->control.hw_key) {1311 switch (info->control.hw_key->cipher) {1312 case WLAN_CIPHER_SUITE_WEP40:1313 case WLAN_CIPHER_SUITE_WEP104:1314 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);1315 break;1316 case WLAN_CIPHER_SUITE_TKIP:1317 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);1318 break;1319 case WLAN_CIPHER_SUITE_CCMP:1320 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);1321 break;1322 default:1323 break;1324 }1325 }1326 1327 tx_buffer_head->current_rate = cpu_to_le16(current_rate);1328 1329 /* legacy rates TODO use ieee80211_tx_rate */1330 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {1331 if (priv->byAutoFBCtrl == AUTO_FB_0)1332 tx_buffer_head->fifo_ctl |=1333 cpu_to_le16(FIFOCTL_AUTO_FB_0);1334 else if (priv->byAutoFBCtrl == AUTO_FB_1)1335 tx_buffer_head->fifo_ctl |=1336 cpu_to_le16(FIFOCTL_AUTO_FB_1);1337 }1338 1339 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);1340 1341 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,1342 dma_idx, head_td, is_pspoll);1343 1344 if (info->control.hw_key) {1345 tx_key = info->control.hw_key;1346 if (tx_key->keylen > 0)1347 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,1348 tx_key, skb, tx_body_size,1349 td_info->mic_hdr);1350 }1351 1352 return 0;1353}1354 1355static int vnt_beacon_xmit(struct vnt_private *priv,1356 struct sk_buff *skb)1357{1358 struct vnt_tx_short_buf_head *short_head =1359 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;1360 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)1361 (priv->tx_beacon_bufs + sizeof(*short_head));1362 struct ieee80211_tx_info *info;1363 u32 frame_size = skb->len + 4;1364 u16 current_rate;1365 1366 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));1367 1368 if (priv->byBBType == BB_TYPE_11A) {1369 current_rate = RATE_6M;1370 1371 /* Get SignalField,ServiceField,Length */1372 vnt_get_phy_field(priv, frame_size, current_rate,1373 PK_TYPE_11A, &short_head->ab);1374 1375 /* Get Duration and TimeStampOff */1376 short_head->duration =1377 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,1378 frame_size, PK_TYPE_11A, current_rate,1379 false, 0, 0, 1, AUTO_FB_NONE));1380 1381 short_head->time_stamp_off =1382 vnt_time_stamp_off(priv, current_rate);1383 } else {1384 current_rate = RATE_1M;1385 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);1386 1387 /* Get SignalField,ServiceField,Length */1388 vnt_get_phy_field(priv, frame_size, current_rate,1389 PK_TYPE_11B, &short_head->ab);1390 1391 /* Get Duration and TimeStampOff */1392 short_head->duration =1393 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,1394 frame_size, PK_TYPE_11B, current_rate,1395 false, 0, 0, 1, AUTO_FB_NONE));1396 1397 short_head->time_stamp_off =1398 vnt_time_stamp_off(priv, current_rate);1399 }1400 1401 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);1402 1403 /* Copy Beacon */1404 memcpy(mgmt_hdr, skb->data, skb->len);1405 1406 /* time stamp always 0 */1407 mgmt_hdr->u.beacon.timestamp = 0;1408 1409 info = IEEE80211_SKB_CB(skb);1410 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {1411 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;1412 1413 hdr->duration_id = 0;1414 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);1415 }1416 1417 priv->wSeqCounter++;1418 if (priv->wSeqCounter > 0x0fff)1419 priv->wSeqCounter = 0;1420 1421 priv->wBCNBufLen = sizeof(*short_head) + skb->len;1422 1423 iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);1424 1425 iowrite16(priv->wBCNBufLen, priv->port_offset + MAC_REG_BCNDMACTL + 2);1426 /* Set auto Transmit on */1427 vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);1428 /* Poll Transmit the adapter */1429 iowrite8(BEACON_READY, priv->port_offset + MAC_REG_BCNDMACTL);1430 1431 return 0;1432}1433 1434int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)1435{1436 struct sk_buff *beacon;1437 1438 beacon = ieee80211_beacon_get(priv->hw, vif, 0);1439 if (!beacon)1440 return -ENOMEM;1441 1442 if (vnt_beacon_xmit(priv, beacon)) {1443 ieee80211_free_txskb(priv->hw, beacon);1444 return -ENODEV;1445 }1446 1447 return 0;1448}1449 1450int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,1451 struct ieee80211_bss_conf *conf)1452{1453 iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL);1454 1455 iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL);1456 1457 CARDvSetFirstNextTBTT(priv, conf->beacon_int);1458 1459 card_set_beacon_period(priv, conf->beacon_int);1460 1461 return vnt_beacon_make(priv, vif);1462}1463