0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "xmit.h"
0018 #include "phy_common.h"
0019 #include "dma.h"
0020 #include "pio.h"
0021
0022 static const struct b43_tx_legacy_rate_phy_ctl_entry b43_tx_legacy_rate_phy_ctl[] = {
0023 { B43_CCK_RATE_1MB, 0x0, 0x0 },
0024 { B43_CCK_RATE_2MB, 0x0, 0x1 },
0025 { B43_CCK_RATE_5MB, 0x0, 0x2 },
0026 { B43_CCK_RATE_11MB, 0x0, 0x3 },
0027 { B43_OFDM_RATE_6MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_BPSK },
0028 { B43_OFDM_RATE_9MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_BPSK },
0029 { B43_OFDM_RATE_12MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QPSK },
0030 { B43_OFDM_RATE_18MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QPSK },
0031 { B43_OFDM_RATE_24MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QAM16 },
0032 { B43_OFDM_RATE_36MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM16 },
0033 { B43_OFDM_RATE_48MB, B43_TXH_PHY1_CRATE_2_3, B43_TXH_PHY1_MODUL_QAM64 },
0034 { B43_OFDM_RATE_54MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM64 },
0035 };
0036
0037 static const struct b43_tx_legacy_rate_phy_ctl_entry *
0038 b43_tx_legacy_rate_phy_ctl_ent(u8 bitrate)
0039 {
0040 const struct b43_tx_legacy_rate_phy_ctl_entry *e;
0041 unsigned int i;
0042
0043 for (i = 0; i < ARRAY_SIZE(b43_tx_legacy_rate_phy_ctl); i++) {
0044 e = &(b43_tx_legacy_rate_phy_ctl[i]);
0045 if (e->bitrate == bitrate)
0046 return e;
0047 }
0048
0049 B43_WARN_ON(1);
0050 return NULL;
0051 }
0052
0053
0054 static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
0055 {
0056 switch (plcp->raw[0]) {
0057 case 0x0A:
0058 return 0;
0059 case 0x14:
0060 return 1;
0061 case 0x37:
0062 return 2;
0063 case 0x6E:
0064 return 3;
0065 }
0066 return -1;
0067 }
0068
0069
0070 static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool ghz5)
0071 {
0072
0073 int base = ghz5 ? 0 : 4;
0074
0075 switch (plcp->raw[0] & 0xF) {
0076 case 0xB:
0077 return base + 0;
0078 case 0xF:
0079 return base + 1;
0080 case 0xA:
0081 return base + 2;
0082 case 0xE:
0083 return base + 3;
0084 case 0x9:
0085 return base + 4;
0086 case 0xD:
0087 return base + 5;
0088 case 0x8:
0089 return base + 6;
0090 case 0xC:
0091 return base + 7;
0092 }
0093 return -1;
0094 }
0095
0096 u8 b43_plcp_get_ratecode_cck(const u8 bitrate)
0097 {
0098 switch (bitrate) {
0099 case B43_CCK_RATE_1MB:
0100 return 0x0A;
0101 case B43_CCK_RATE_2MB:
0102 return 0x14;
0103 case B43_CCK_RATE_5MB:
0104 return 0x37;
0105 case B43_CCK_RATE_11MB:
0106 return 0x6E;
0107 }
0108 B43_WARN_ON(1);
0109 return 0;
0110 }
0111
0112 u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate)
0113 {
0114 switch (bitrate) {
0115 case B43_OFDM_RATE_6MB:
0116 return 0xB;
0117 case B43_OFDM_RATE_9MB:
0118 return 0xF;
0119 case B43_OFDM_RATE_12MB:
0120 return 0xA;
0121 case B43_OFDM_RATE_18MB:
0122 return 0xE;
0123 case B43_OFDM_RATE_24MB:
0124 return 0x9;
0125 case B43_OFDM_RATE_36MB:
0126 return 0xD;
0127 case B43_OFDM_RATE_48MB:
0128 return 0x8;
0129 case B43_OFDM_RATE_54MB:
0130 return 0xC;
0131 }
0132 B43_WARN_ON(1);
0133 return 0;
0134 }
0135
0136 void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
0137 const u16 octets, const u8 bitrate)
0138 {
0139 __u8 *raw = plcp->raw;
0140
0141 if (b43_is_ofdm_rate(bitrate)) {
0142 u32 d;
0143
0144 d = b43_plcp_get_ratecode_ofdm(bitrate);
0145 B43_WARN_ON(octets & 0xF000);
0146 d |= (octets << 5);
0147 plcp->data = cpu_to_le32(d);
0148 } else {
0149 u32 plen;
0150
0151 plen = octets * 16 / bitrate;
0152 if ((octets * 16 % bitrate) > 0) {
0153 plen++;
0154 if ((bitrate == B43_CCK_RATE_11MB)
0155 && ((octets * 8 % 11) < 4)) {
0156 raw[1] = 0x84;
0157 } else
0158 raw[1] = 0x04;
0159 } else
0160 raw[1] = 0x04;
0161 plcp->data |= cpu_to_le32(plen << 16);
0162 raw[0] = b43_plcp_get_ratecode_cck(bitrate);
0163 }
0164 }
0165
0166
0167 static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
0168 {
0169 const struct b43_phy *phy = &dev->phy;
0170 const struct b43_tx_legacy_rate_phy_ctl_entry *e;
0171 u16 control = 0;
0172 u16 bw;
0173
0174 if (phy->type == B43_PHYTYPE_LP)
0175 bw = B43_TXH_PHY1_BW_20;
0176 else
0177 bw = B43_TXH_PHY1_BW_20;
0178
0179 if (0) {
0180 } else if (b43_is_cck_rate(bitrate) && phy->type != B43_PHYTYPE_LP) {
0181 control = bw;
0182 } else {
0183 control = bw;
0184 e = b43_tx_legacy_rate_phy_ctl_ent(bitrate);
0185 if (e) {
0186 control |= e->coding_rate;
0187 control |= e->modulation;
0188 }
0189 control |= B43_TXH_PHY1_MODE_SISO;
0190 }
0191
0192 return control;
0193 }
0194
0195 static u8 b43_calc_fallback_rate(u8 bitrate, int gmode)
0196 {
0197 switch (bitrate) {
0198 case B43_CCK_RATE_1MB:
0199 return B43_CCK_RATE_1MB;
0200 case B43_CCK_RATE_2MB:
0201 return B43_CCK_RATE_1MB;
0202 case B43_CCK_RATE_5MB:
0203 return B43_CCK_RATE_2MB;
0204 case B43_CCK_RATE_11MB:
0205 return B43_CCK_RATE_5MB;
0206
0207
0208
0209
0210 case B43_OFDM_RATE_6MB:
0211 if (gmode)
0212 return B43_CCK_RATE_5MB;
0213 else
0214 return B43_OFDM_RATE_6MB;
0215 case B43_OFDM_RATE_9MB:
0216 return B43_OFDM_RATE_6MB;
0217 case B43_OFDM_RATE_12MB:
0218 return B43_OFDM_RATE_9MB;
0219 case B43_OFDM_RATE_18MB:
0220 return B43_OFDM_RATE_12MB;
0221 case B43_OFDM_RATE_24MB:
0222 return B43_OFDM_RATE_18MB;
0223 case B43_OFDM_RATE_36MB:
0224 return B43_OFDM_RATE_24MB;
0225 case B43_OFDM_RATE_48MB:
0226 return B43_OFDM_RATE_36MB;
0227 case B43_OFDM_RATE_54MB:
0228 return B43_OFDM_RATE_48MB;
0229 }
0230 B43_WARN_ON(1);
0231 return 0;
0232 }
0233
0234
0235 int b43_generate_txhdr(struct b43_wldev *dev,
0236 u8 *_txhdr,
0237 struct sk_buff *skb_frag,
0238 struct ieee80211_tx_info *info,
0239 u16 cookie)
0240 {
0241 const unsigned char *fragment_data = skb_frag->data;
0242 unsigned int fragment_len = skb_frag->len;
0243 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
0244 const struct b43_phy *phy = &dev->phy;
0245 const struct ieee80211_hdr *wlhdr =
0246 (const struct ieee80211_hdr *)fragment_data;
0247 int use_encryption = !!info->control.hw_key;
0248 __le16 fctl = wlhdr->frame_control;
0249 struct ieee80211_rate *fbrate;
0250 u8 rate, rate_fb;
0251 int rate_ofdm, rate_fb_ofdm;
0252 unsigned int plcp_fragment_len;
0253 u32 mac_ctl = 0;
0254 u16 phy_ctl = 0;
0255 bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP ||
0256 phy->type == B43_PHYTYPE_N ||
0257 phy->type == B43_PHYTYPE_HT);
0258 u8 extra_ft = 0;
0259 struct ieee80211_rate *txrate;
0260 struct ieee80211_tx_rate *rates;
0261
0262 memset(txhdr, 0, sizeof(*txhdr));
0263
0264 txrate = ieee80211_get_tx_rate(dev->wl->hw, info);
0265 rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
0266 rate_ofdm = b43_is_ofdm_rate(rate);
0267 fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : txrate;
0268 rate_fb = fbrate->hw_value;
0269 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
0270
0271 if (rate_ofdm)
0272 txhdr->phy_rate = b43_plcp_get_ratecode_ofdm(rate);
0273 else
0274 txhdr->phy_rate = b43_plcp_get_ratecode_cck(rate);
0275 txhdr->mac_frame_ctl = wlhdr->frame_control;
0276 memcpy(txhdr->tx_receiver, wlhdr->addr1, ETH_ALEN);
0277
0278
0279 if ((rate_fb == rate) ||
0280 (wlhdr->duration_id & cpu_to_le16(0x8000)) ||
0281 (wlhdr->duration_id == cpu_to_le16(0))) {
0282
0283
0284
0285 txhdr->dur_fb = wlhdr->duration_id;
0286 } else {
0287 txhdr->dur_fb = ieee80211_generic_frame_duration(
0288 dev->wl->hw, info->control.vif, info->band,
0289 fragment_len, fbrate);
0290 }
0291
0292 plcp_fragment_len = fragment_len + FCS_LEN;
0293 if (use_encryption) {
0294 u8 key_idx = info->control.hw_key->hw_key_idx;
0295 struct b43_key *key;
0296 int wlhdr_len;
0297 size_t iv_len;
0298
0299 B43_WARN_ON(key_idx >= ARRAY_SIZE(dev->key));
0300 key = &(dev->key[key_idx]);
0301
0302 if (unlikely(!key->keyconf)) {
0303
0304
0305
0306
0307
0308 return -ENOKEY;
0309 }
0310
0311
0312 plcp_fragment_len += info->control.hw_key->icv_len;
0313
0314 key_idx = b43_kidx_to_fw(dev, key_idx);
0315 mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
0316 B43_TXH_MAC_KEYIDX;
0317 mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
0318 B43_TXH_MAC_KEYALG;
0319 wlhdr_len = ieee80211_hdrlen(fctl);
0320 if (key->algorithm == B43_SEC_ALGO_TKIP) {
0321 u16 phase1key[5];
0322 int i;
0323
0324
0325
0326 ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key);
0327
0328 for (i = 0; i < 5; i++) {
0329 txhdr->iv[i * 2 + 0] = phase1key[i];
0330 txhdr->iv[i * 2 + 1] = phase1key[i] >> 8;
0331 }
0332
0333 memcpy(txhdr->iv + 10, ((u8 *) wlhdr) + wlhdr_len, 3);
0334 } else {
0335 iv_len = min_t(size_t, info->control.hw_key->iv_len,
0336 ARRAY_SIZE(txhdr->iv));
0337 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
0338 }
0339 }
0340 switch (dev->fw.hdr_format) {
0341 case B43_FW_HDR_598:
0342 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_598.plcp),
0343 plcp_fragment_len, rate);
0344 break;
0345 case B43_FW_HDR_351:
0346 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_351.plcp),
0347 plcp_fragment_len, rate);
0348 break;
0349 case B43_FW_HDR_410:
0350 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_410.plcp),
0351 plcp_fragment_len, rate);
0352 break;
0353 }
0354 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb),
0355 plcp_fragment_len, rate_fb);
0356
0357
0358 if (rate_fb_ofdm)
0359 extra_ft |= B43_TXH_EFT_FB_OFDM;
0360 else
0361 extra_ft |= B43_TXH_EFT_FB_CCK;
0362
0363
0364
0365
0366
0367 txhdr->chan_radio_code = phy->channel;
0368
0369
0370 if (rate_ofdm)
0371 phy_ctl |= B43_TXH_PHY_ENC_OFDM;
0372 else
0373 phy_ctl |= B43_TXH_PHY_ENC_CCK;
0374 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
0375 phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
0376
0377 switch (b43_ieee80211_antenna_sanitize(dev, 0)) {
0378 case 0:
0379 phy_ctl |= B43_TXH_PHY_ANT01AUTO;
0380 break;
0381 case 1:
0382 phy_ctl |= B43_TXH_PHY_ANT0;
0383 break;
0384 case 2:
0385 phy_ctl |= B43_TXH_PHY_ANT1;
0386 break;
0387 case 3:
0388 phy_ctl |= B43_TXH_PHY_ANT2;
0389 break;
0390 case 4:
0391 phy_ctl |= B43_TXH_PHY_ANT3;
0392 break;
0393 default:
0394 B43_WARN_ON(1);
0395 }
0396
0397 rates = info->control.rates;
0398
0399 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
0400 mac_ctl |= B43_TXH_MAC_ACK;
0401
0402 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
0403 mac_ctl |= B43_TXH_MAC_HWSEQ;
0404 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
0405 mac_ctl |= B43_TXH_MAC_STMSDU;
0406 if (!phy->gmode)
0407 mac_ctl |= B43_TXH_MAC_5GHZ;
0408
0409
0410
0411
0412
0413 if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
0414 (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) {
0415 rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count;
0416 mac_ctl |= B43_TXH_MAC_LONGFRAME;
0417 } else {
0418 rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count;
0419 }
0420
0421
0422 if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
0423 (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
0424 unsigned int len;
0425 struct ieee80211_hdr *hdr;
0426 int rts_rate, rts_rate_fb;
0427 int rts_rate_ofdm, rts_rate_fb_ofdm;
0428 struct b43_plcp_hdr6 *plcp;
0429 struct ieee80211_rate *rts_cts_rate;
0430
0431 rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info);
0432
0433 rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
0434 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
0435 rts_rate_fb = b43_calc_fallback_rate(rts_rate, phy->gmode);
0436 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
0437
0438 if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
0439 struct ieee80211_cts *cts;
0440
0441 switch (dev->fw.hdr_format) {
0442 case B43_FW_HDR_598:
0443 cts = (struct ieee80211_cts *)
0444 (txhdr->format_598.rts_frame);
0445 break;
0446 case B43_FW_HDR_351:
0447 cts = (struct ieee80211_cts *)
0448 (txhdr->format_351.rts_frame);
0449 break;
0450 case B43_FW_HDR_410:
0451 cts = (struct ieee80211_cts *)
0452 (txhdr->format_410.rts_frame);
0453 break;
0454 }
0455 ieee80211_ctstoself_get(dev->wl->hw, info->control.vif,
0456 fragment_data, fragment_len,
0457 info, cts);
0458 mac_ctl |= B43_TXH_MAC_SENDCTS;
0459 len = sizeof(struct ieee80211_cts);
0460 } else {
0461 struct ieee80211_rts *rts;
0462
0463 switch (dev->fw.hdr_format) {
0464 case B43_FW_HDR_598:
0465 rts = (struct ieee80211_rts *)
0466 (txhdr->format_598.rts_frame);
0467 break;
0468 case B43_FW_HDR_351:
0469 rts = (struct ieee80211_rts *)
0470 (txhdr->format_351.rts_frame);
0471 break;
0472 case B43_FW_HDR_410:
0473 rts = (struct ieee80211_rts *)
0474 (txhdr->format_410.rts_frame);
0475 break;
0476 }
0477 ieee80211_rts_get(dev->wl->hw, info->control.vif,
0478 fragment_data, fragment_len,
0479 info, rts);
0480 mac_ctl |= B43_TXH_MAC_SENDRTS;
0481 len = sizeof(struct ieee80211_rts);
0482 }
0483 len += FCS_LEN;
0484
0485
0486 switch (dev->fw.hdr_format) {
0487 case B43_FW_HDR_598:
0488 plcp = &txhdr->format_598.rts_plcp;
0489 break;
0490 case B43_FW_HDR_351:
0491 plcp = &txhdr->format_351.rts_plcp;
0492 break;
0493 case B43_FW_HDR_410:
0494 plcp = &txhdr->format_410.rts_plcp;
0495 break;
0496 }
0497 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
0498 len, rts_rate);
0499 plcp = &txhdr->rts_plcp_fb;
0500 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
0501 len, rts_rate_fb);
0502
0503 switch (dev->fw.hdr_format) {
0504 case B43_FW_HDR_598:
0505 hdr = (struct ieee80211_hdr *)
0506 (&txhdr->format_598.rts_frame);
0507 break;
0508 case B43_FW_HDR_351:
0509 hdr = (struct ieee80211_hdr *)
0510 (&txhdr->format_351.rts_frame);
0511 break;
0512 case B43_FW_HDR_410:
0513 hdr = (struct ieee80211_hdr *)
0514 (&txhdr->format_410.rts_frame);
0515 break;
0516 }
0517 txhdr->rts_dur_fb = hdr->duration_id;
0518
0519 if (rts_rate_ofdm) {
0520 extra_ft |= B43_TXH_EFT_RTS_OFDM;
0521 txhdr->phy_rate_rts =
0522 b43_plcp_get_ratecode_ofdm(rts_rate);
0523 } else {
0524 extra_ft |= B43_TXH_EFT_RTS_CCK;
0525 txhdr->phy_rate_rts =
0526 b43_plcp_get_ratecode_cck(rts_rate);
0527 }
0528 if (rts_rate_fb_ofdm)
0529 extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
0530 else
0531 extra_ft |= B43_TXH_EFT_RTSFB_CCK;
0532
0533 if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
0534 fill_phy_ctl1) {
0535 txhdr->phy_ctl1_rts = cpu_to_le16(
0536 b43_generate_tx_phy_ctl1(dev, rts_rate));
0537 txhdr->phy_ctl1_rts_fb = cpu_to_le16(
0538 b43_generate_tx_phy_ctl1(dev, rts_rate_fb));
0539 }
0540 }
0541
0542
0543 switch (dev->fw.hdr_format) {
0544 case B43_FW_HDR_598:
0545 txhdr->format_598.cookie = cpu_to_le16(cookie);
0546 break;
0547 case B43_FW_HDR_351:
0548 txhdr->format_351.cookie = cpu_to_le16(cookie);
0549 break;
0550 case B43_FW_HDR_410:
0551 txhdr->format_410.cookie = cpu_to_le16(cookie);
0552 break;
0553 }
0554
0555 if (fill_phy_ctl1) {
0556 txhdr->phy_ctl1 =
0557 cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
0558 txhdr->phy_ctl1_fb =
0559 cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate_fb));
0560 }
0561
0562
0563 txhdr->mac_ctl = cpu_to_le32(mac_ctl);
0564 txhdr->phy_ctl = cpu_to_le16(phy_ctl);
0565 txhdr->extra_ft = extra_ft;
0566
0567 return 0;
0568 }
0569
0570 static s8 b43_rssi_postprocess(struct b43_wldev *dev,
0571 u8 in_rssi, int ofdm,
0572 int adjust_2053, int adjust_2050)
0573 {
0574 struct b43_phy *phy = &dev->phy;
0575 struct b43_phy_g *gphy = phy->g;
0576 s32 tmp;
0577
0578 switch (phy->radio_ver) {
0579 case 0x2050:
0580 if (ofdm) {
0581 tmp = in_rssi;
0582 if (tmp > 127)
0583 tmp -= 256;
0584 tmp *= 73;
0585 tmp /= 64;
0586 if (adjust_2050)
0587 tmp += 25;
0588 else
0589 tmp -= 3;
0590 } else {
0591 if (dev->dev->bus_sprom->
0592 boardflags_lo & B43_BFL_RSSI) {
0593 if (in_rssi > 63)
0594 in_rssi = 63;
0595 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
0596 tmp = gphy->nrssi_lt[in_rssi];
0597 tmp = 31 - tmp;
0598 tmp *= -131;
0599 tmp /= 128;
0600 tmp -= 57;
0601 } else {
0602 tmp = in_rssi;
0603 tmp = 31 - tmp;
0604 tmp *= -149;
0605 tmp /= 128;
0606 tmp -= 68;
0607 }
0608 if (phy->type == B43_PHYTYPE_G && adjust_2050)
0609 tmp += 25;
0610 }
0611 break;
0612 case 0x2060:
0613 if (in_rssi > 127)
0614 tmp = in_rssi - 256;
0615 else
0616 tmp = in_rssi;
0617 break;
0618 default:
0619 tmp = in_rssi;
0620 tmp -= 11;
0621 tmp *= 103;
0622 tmp /= 64;
0623 if (adjust_2053)
0624 tmp -= 109;
0625 else
0626 tmp -= 83;
0627 }
0628
0629 return (s8) tmp;
0630 }
0631
0632 void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
0633 {
0634 struct ieee80211_rx_status status;
0635 struct b43_plcp_hdr6 *plcp;
0636 struct ieee80211_hdr *wlhdr;
0637 const struct b43_rxhdr_fw4 *rxhdr = _rxhdr;
0638 __le16 fctl;
0639 u16 phystat0, phystat3;
0640 u16 chanstat, mactime;
0641 u32 macstat;
0642 u16 chanid;
0643 int padding, rate_idx;
0644
0645 memset(&status, 0, sizeof(status));
0646
0647
0648 phystat0 = le16_to_cpu(rxhdr->phy_status0);
0649 phystat3 = le16_to_cpu(rxhdr->phy_status3);
0650 switch (dev->fw.hdr_format) {
0651 case B43_FW_HDR_598:
0652 macstat = le32_to_cpu(rxhdr->format_598.mac_status);
0653 mactime = le16_to_cpu(rxhdr->format_598.mac_time);
0654 chanstat = le16_to_cpu(rxhdr->format_598.channel);
0655 break;
0656 case B43_FW_HDR_410:
0657 case B43_FW_HDR_351:
0658 macstat = le32_to_cpu(rxhdr->format_351.mac_status);
0659 mactime = le16_to_cpu(rxhdr->format_351.mac_time);
0660 chanstat = le16_to_cpu(rxhdr->format_351.channel);
0661 break;
0662 }
0663
0664 if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
0665 dev->wl->ieee_stats.dot11FCSErrorCount++;
0666 status.flag |= RX_FLAG_FAILED_FCS_CRC;
0667 }
0668 if (unlikely(phystat0 & (B43_RX_PHYST0_PLCPHCF | B43_RX_PHYST0_PLCPFV)))
0669 status.flag |= RX_FLAG_FAILED_PLCP_CRC;
0670 if (phystat0 & B43_RX_PHYST0_SHORTPRMBL)
0671 status.enc_flags |= RX_ENC_FLAG_SHORTPRE;
0672 if (macstat & B43_RX_MAC_DECERR) {
0673
0674
0675
0676 goto drop;
0677 }
0678
0679
0680 padding = (macstat & B43_RX_MAC_PADDING) ? 2 : 0;
0681 if (unlikely(skb->len < (sizeof(struct b43_plcp_hdr6) + padding))) {
0682 b43dbg(dev->wl, "RX: Packet size underrun (1)\n");
0683 goto drop;
0684 }
0685 plcp = (struct b43_plcp_hdr6 *)(skb->data + padding);
0686 skb_pull(skb, sizeof(struct b43_plcp_hdr6) + padding);
0687
0688 if (unlikely(skb->len < (2 + 2 + 6 + FCS_LEN))) {
0689 b43dbg(dev->wl, "RX: Packet size underrun (2)\n");
0690 goto drop;
0691 }
0692 wlhdr = (struct ieee80211_hdr *)(skb->data);
0693 fctl = wlhdr->frame_control;
0694
0695 if (macstat & B43_RX_MAC_DEC) {
0696 unsigned int keyidx;
0697 int wlhdr_len;
0698
0699 keyidx = ((macstat & B43_RX_MAC_KEYIDX)
0700 >> B43_RX_MAC_KEYIDX_SHIFT);
0701
0702
0703
0704 keyidx = b43_kidx_to_raw(dev, keyidx);
0705 B43_WARN_ON(keyidx >= ARRAY_SIZE(dev->key));
0706
0707 if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
0708 wlhdr_len = ieee80211_hdrlen(fctl);
0709 if (unlikely(skb->len < (wlhdr_len + 3))) {
0710 b43dbg(dev->wl,
0711 "RX: Packet size underrun (3)\n");
0712 goto drop;
0713 }
0714 status.flag |= RX_FLAG_DECRYPTED;
0715 }
0716 }
0717
0718
0719 switch (chanstat & B43_RX_CHAN_PHYTYPE) {
0720 case B43_PHYTYPE_HT:
0721
0722 status.signal = max_t(__s8,
0723 max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1),
0724 rxhdr->phy_ht_power2);
0725 break;
0726 case B43_PHYTYPE_N:
0727
0728 if (rxhdr->power0 == 16 || rxhdr->power0 == 32)
0729 status.signal = max(rxhdr->power1, rxhdr->power2);
0730 else
0731 status.signal = max(rxhdr->power0, rxhdr->power1);
0732 break;
0733 case B43_PHYTYPE_B:
0734 case B43_PHYTYPE_G:
0735 case B43_PHYTYPE_LP:
0736 status.signal = b43_rssi_postprocess(dev, rxhdr->jssi,
0737 (phystat0 & B43_RX_PHYST0_OFDM),
0738 (phystat0 & B43_RX_PHYST0_GAINCTL),
0739 (phystat3 & B43_RX_PHYST3_TRSTATE));
0740 break;
0741 }
0742
0743 if (phystat0 & B43_RX_PHYST0_OFDM)
0744 rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
0745 !!(chanstat & B43_RX_CHAN_5GHZ));
0746 else
0747 rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
0748 if (unlikely(rate_idx == -1)) {
0749
0750
0751 if (!(dev->wl->filter_flags & FIF_PLCPFAIL))
0752 goto drop;
0753 }
0754 status.rate_idx = rate_idx;
0755 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765 if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
0766 u16 low_mactime_now;
0767
0768 b43_tsf_read(dev, &status.mactime);
0769 low_mactime_now = status.mactime;
0770 status.mactime = status.mactime & ~0xFFFFULL;
0771 status.mactime += mactime;
0772 if (low_mactime_now <= mactime)
0773 status.mactime -= 0x10000;
0774 status.flag |= RX_FLAG_MACTIME_START;
0775 }
0776
0777 chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
0778 switch (chanstat & B43_RX_CHAN_PHYTYPE) {
0779 case B43_PHYTYPE_G:
0780 status.band = NL80211_BAND_2GHZ;
0781
0782
0783
0784 if (dev->fw.rev >= 508)
0785 status.freq = ieee80211_channel_to_frequency(chanid, status.band);
0786 else
0787 status.freq = chanid + 2400;
0788 break;
0789 case B43_PHYTYPE_N:
0790 case B43_PHYTYPE_LP:
0791 case B43_PHYTYPE_HT:
0792
0793
0794 if (chanstat & B43_RX_CHAN_5GHZ)
0795 status.band = NL80211_BAND_5GHZ;
0796 else
0797 status.band = NL80211_BAND_2GHZ;
0798 status.freq =
0799 ieee80211_channel_to_frequency(chanid, status.band);
0800 break;
0801 default:
0802 B43_WARN_ON(1);
0803 goto drop;
0804 }
0805
0806 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
0807 ieee80211_rx_ni(dev->wl->hw, skb);
0808
0809 #if B43_DEBUG
0810 dev->rx_count++;
0811 #endif
0812 return;
0813 drop:
0814 dev_kfree_skb_any(skb);
0815 }
0816
0817 void b43_handle_txstatus(struct b43_wldev *dev,
0818 const struct b43_txstatus *status)
0819 {
0820 b43_debugfs_log_txstat(dev, status);
0821
0822 if (status->intermediate)
0823 return;
0824 if (status->for_ampdu)
0825 return;
0826 if (!status->acked)
0827 dev->wl->ieee_stats.dot11ACKFailureCount++;
0828 if (status->rts_count) {
0829 if (status->rts_count == 0xF)
0830 dev->wl->ieee_stats.dot11RTSFailureCount++;
0831 else
0832 dev->wl->ieee_stats.dot11RTSSuccessCount++;
0833 }
0834
0835 if (b43_using_pio_transfers(dev))
0836 b43_pio_handle_txstatus(dev, status);
0837 else
0838 b43_dma_handle_txstatus(dev, status);
0839
0840 b43_phy_txpower_check(dev, 0);
0841 }
0842
0843
0844
0845
0846 bool b43_fill_txstatus_report(struct b43_wldev *dev,
0847 struct ieee80211_tx_info *report,
0848 const struct b43_txstatus *status)
0849 {
0850 bool frame_success = true;
0851 int retry_limit;
0852
0853
0854
0855
0856 retry_limit = report->status.rates[0].count;
0857 ieee80211_tx_info_clear_status(report);
0858
0859 if (status->acked) {
0860
0861 report->flags |= IEEE80211_TX_STAT_ACK;
0862 } else {
0863
0864 if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) {
0865
0866 frame_success = false;
0867 }
0868 }
0869 if (status->frame_count == 0) {
0870
0871 report->status.rates[0].count = 0;
0872 } else if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) {
0873
0874
0875
0876
0877
0878
0879
0880 report->status.rates[0].count = 0;
0881 report->status.rates[1].count = status->frame_count;
0882 } else {
0883 if (status->frame_count > retry_limit) {
0884 report->status.rates[0].count = retry_limit;
0885 report->status.rates[1].count = status->frame_count -
0886 retry_limit;
0887
0888 } else {
0889 report->status.rates[0].count = status->frame_count;
0890 report->status.rates[1].idx = -1;
0891 }
0892 }
0893
0894 return frame_success;
0895 }
0896
0897
0898 void b43_tx_suspend(struct b43_wldev *dev)
0899 {
0900 if (b43_using_pio_transfers(dev))
0901 b43_pio_tx_suspend(dev);
0902 else
0903 b43_dma_tx_suspend(dev);
0904 }
0905
0906
0907 void b43_tx_resume(struct b43_wldev *dev)
0908 {
0909 if (b43_using_pio_transfers(dev))
0910 b43_pio_tx_resume(dev);
0911 else
0912 b43_dma_tx_resume(dev);
0913 }