Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.13-rc2 942 lines 26 kB view raw
1/* 2 3 Broadcom B43 wireless driver 4 5 Transmission (TX/RX) related functions. 6 7 Copyright (C) 2005 Martin Langer <martin-langer@gmx.de> 8 Copyright (C) 2005 Stefano Brivio <stefano.brivio@polimi.it> 9 Copyright (C) 2005, 2006 Michael Buesch <m@bues.ch> 10 Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org> 11 Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> 12 13 This program is free software; you can redistribute it and/or modify 14 it under the terms of the GNU General Public License as published by 15 the Free Software Foundation; either version 2 of the License, or 16 (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 GNU General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; see the file COPYING. If not, write to 25 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, 26 Boston, MA 02110-1301, USA. 27 28*/ 29 30#include "xmit.h" 31#include "phy_common.h" 32#include "dma.h" 33#include "pio.h" 34 35static const struct b43_tx_legacy_rate_phy_ctl_entry b43_tx_legacy_rate_phy_ctl[] = { 36 { B43_CCK_RATE_1MB, 0x0, 0x0 }, 37 { B43_CCK_RATE_2MB, 0x0, 0x1 }, 38 { B43_CCK_RATE_5MB, 0x0, 0x2 }, 39 { B43_CCK_RATE_11MB, 0x0, 0x3 }, 40 { B43_OFDM_RATE_6MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_BPSK }, 41 { B43_OFDM_RATE_9MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_BPSK }, 42 { B43_OFDM_RATE_12MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QPSK }, 43 { B43_OFDM_RATE_18MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QPSK }, 44 { B43_OFDM_RATE_24MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QAM16 }, 45 { B43_OFDM_RATE_36MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM16 }, 46 { B43_OFDM_RATE_48MB, B43_TXH_PHY1_CRATE_2_3, B43_TXH_PHY1_MODUL_QAM64 }, 47 { B43_OFDM_RATE_54MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM64 }, 48}; 49 50static const struct b43_tx_legacy_rate_phy_ctl_entry * 51b43_tx_legacy_rate_phy_ctl_ent(u8 bitrate) 52{ 53 const struct b43_tx_legacy_rate_phy_ctl_entry *e; 54 unsigned int i; 55 56 for (i = 0; i < ARRAY_SIZE(b43_tx_legacy_rate_phy_ctl); i++) { 57 e = &(b43_tx_legacy_rate_phy_ctl[i]); 58 if (e->bitrate == bitrate) 59 return e; 60 } 61 62 B43_WARN_ON(1); 63 return NULL; 64} 65 66/* Extract the bitrate index out of a CCK PLCP header. */ 67static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp) 68{ 69 switch (plcp->raw[0]) { 70 case 0x0A: 71 return 0; 72 case 0x14: 73 return 1; 74 case 0x37: 75 return 2; 76 case 0x6E: 77 return 3; 78 } 79 return -1; 80} 81 82/* Extract the bitrate index out of an OFDM PLCP header. */ 83static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy) 84{ 85 int base = aphy ? 0 : 4; 86 87 switch (plcp->raw[0] & 0xF) { 88 case 0xB: 89 return base + 0; 90 case 0xF: 91 return base + 1; 92 case 0xA: 93 return base + 2; 94 case 0xE: 95 return base + 3; 96 case 0x9: 97 return base + 4; 98 case 0xD: 99 return base + 5; 100 case 0x8: 101 return base + 6; 102 case 0xC: 103 return base + 7; 104 } 105 return -1; 106} 107 108u8 b43_plcp_get_ratecode_cck(const u8 bitrate) 109{ 110 switch (bitrate) { 111 case B43_CCK_RATE_1MB: 112 return 0x0A; 113 case B43_CCK_RATE_2MB: 114 return 0x14; 115 case B43_CCK_RATE_5MB: 116 return 0x37; 117 case B43_CCK_RATE_11MB: 118 return 0x6E; 119 } 120 B43_WARN_ON(1); 121 return 0; 122} 123 124u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate) 125{ 126 switch (bitrate) { 127 case B43_OFDM_RATE_6MB: 128 return 0xB; 129 case B43_OFDM_RATE_9MB: 130 return 0xF; 131 case B43_OFDM_RATE_12MB: 132 return 0xA; 133 case B43_OFDM_RATE_18MB: 134 return 0xE; 135 case B43_OFDM_RATE_24MB: 136 return 0x9; 137 case B43_OFDM_RATE_36MB: 138 return 0xD; 139 case B43_OFDM_RATE_48MB: 140 return 0x8; 141 case B43_OFDM_RATE_54MB: 142 return 0xC; 143 } 144 B43_WARN_ON(1); 145 return 0; 146} 147 148void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, 149 const u16 octets, const u8 bitrate) 150{ 151 __u8 *raw = plcp->raw; 152 153 if (b43_is_ofdm_rate(bitrate)) { 154 u32 d; 155 156 d = b43_plcp_get_ratecode_ofdm(bitrate); 157 B43_WARN_ON(octets & 0xF000); 158 d |= (octets << 5); 159 plcp->data = cpu_to_le32(d); 160 } else { 161 u32 plen; 162 163 plen = octets * 16 / bitrate; 164 if ((octets * 16 % bitrate) > 0) { 165 plen++; 166 if ((bitrate == B43_CCK_RATE_11MB) 167 && ((octets * 8 % 11) < 4)) { 168 raw[1] = 0x84; 169 } else 170 raw[1] = 0x04; 171 } else 172 raw[1] = 0x04; 173 plcp->data |= cpu_to_le32(plen << 16); 174 raw[0] = b43_plcp_get_ratecode_cck(bitrate); 175 } 176} 177 178/* TODO: verify if needed for SSLPN or LCN */ 179static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate) 180{ 181 const struct b43_phy *phy = &dev->phy; 182 const struct b43_tx_legacy_rate_phy_ctl_entry *e; 183 u16 control = 0; 184 u16 bw; 185 186 if (phy->type == B43_PHYTYPE_LP) 187 bw = B43_TXH_PHY1_BW_20; 188 else /* FIXME */ 189 bw = B43_TXH_PHY1_BW_20; 190 191 if (0) { /* FIXME: MIMO */ 192 } else if (b43_is_cck_rate(bitrate) && phy->type != B43_PHYTYPE_LP) { 193 control = bw; 194 } else { 195 control = bw; 196 e = b43_tx_legacy_rate_phy_ctl_ent(bitrate); 197 if (e) { 198 control |= e->coding_rate; 199 control |= e->modulation; 200 } 201 control |= B43_TXH_PHY1_MODE_SISO; 202 } 203 204 return control; 205} 206 207static u8 b43_calc_fallback_rate(u8 bitrate) 208{ 209 switch (bitrate) { 210 case B43_CCK_RATE_1MB: 211 return B43_CCK_RATE_1MB; 212 case B43_CCK_RATE_2MB: 213 return B43_CCK_RATE_1MB; 214 case B43_CCK_RATE_5MB: 215 return B43_CCK_RATE_2MB; 216 case B43_CCK_RATE_11MB: 217 return B43_CCK_RATE_5MB; 218 case B43_OFDM_RATE_6MB: 219 return B43_CCK_RATE_5MB; 220 case B43_OFDM_RATE_9MB: 221 return B43_OFDM_RATE_6MB; 222 case B43_OFDM_RATE_12MB: 223 return B43_OFDM_RATE_9MB; 224 case B43_OFDM_RATE_18MB: 225 return B43_OFDM_RATE_12MB; 226 case B43_OFDM_RATE_24MB: 227 return B43_OFDM_RATE_18MB; 228 case B43_OFDM_RATE_36MB: 229 return B43_OFDM_RATE_24MB; 230 case B43_OFDM_RATE_48MB: 231 return B43_OFDM_RATE_36MB; 232 case B43_OFDM_RATE_54MB: 233 return B43_OFDM_RATE_48MB; 234 } 235 B43_WARN_ON(1); 236 return 0; 237} 238 239/* Generate a TX data header. */ 240int b43_generate_txhdr(struct b43_wldev *dev, 241 u8 *_txhdr, 242 struct sk_buff *skb_frag, 243 struct ieee80211_tx_info *info, 244 u16 cookie) 245{ 246 const unsigned char *fragment_data = skb_frag->data; 247 unsigned int fragment_len = skb_frag->len; 248 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr; 249 const struct b43_phy *phy = &dev->phy; 250 const struct ieee80211_hdr *wlhdr = 251 (const struct ieee80211_hdr *)fragment_data; 252 int use_encryption = !!info->control.hw_key; 253 __le16 fctl = wlhdr->frame_control; 254 struct ieee80211_rate *fbrate; 255 u8 rate, rate_fb; 256 int rate_ofdm, rate_fb_ofdm; 257 unsigned int plcp_fragment_len; 258 u32 mac_ctl = 0; 259 u16 phy_ctl = 0; 260 bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP || 261 phy->type == B43_PHYTYPE_N || 262 phy->type == B43_PHYTYPE_HT); 263 u8 extra_ft = 0; 264 struct ieee80211_rate *txrate; 265 struct ieee80211_tx_rate *rates; 266 267 memset(txhdr, 0, sizeof(*txhdr)); 268 269 txrate = ieee80211_get_tx_rate(dev->wl->hw, info); 270 rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB; 271 rate_ofdm = b43_is_ofdm_rate(rate); 272 fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : txrate; 273 rate_fb = fbrate->hw_value; 274 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); 275 276 if (rate_ofdm) 277 txhdr->phy_rate = b43_plcp_get_ratecode_ofdm(rate); 278 else 279 txhdr->phy_rate = b43_plcp_get_ratecode_cck(rate); 280 txhdr->mac_frame_ctl = wlhdr->frame_control; 281 memcpy(txhdr->tx_receiver, wlhdr->addr1, ETH_ALEN); 282 283 /* Calculate duration for fallback rate */ 284 if ((rate_fb == rate) || 285 (wlhdr->duration_id & cpu_to_le16(0x8000)) || 286 (wlhdr->duration_id == cpu_to_le16(0))) { 287 /* If the fallback rate equals the normal rate or the 288 * dur_id field contains an AID, CFP magic or 0, 289 * use the original dur_id field. */ 290 txhdr->dur_fb = wlhdr->duration_id; 291 } else { 292 txhdr->dur_fb = ieee80211_generic_frame_duration( 293 dev->wl->hw, info->control.vif, info->band, 294 fragment_len, fbrate); 295 } 296 297 plcp_fragment_len = fragment_len + FCS_LEN; 298 if (use_encryption) { 299 u8 key_idx = info->control.hw_key->hw_key_idx; 300 struct b43_key *key; 301 int wlhdr_len; 302 size_t iv_len; 303 304 B43_WARN_ON(key_idx >= ARRAY_SIZE(dev->key)); 305 key = &(dev->key[key_idx]); 306 307 if (unlikely(!key->keyconf)) { 308 /* This key is invalid. This might only happen 309 * in a short timeframe after machine resume before 310 * we were able to reconfigure keys. 311 * Drop this packet completely. Do not transmit it 312 * unencrypted to avoid leaking information. */ 313 return -ENOKEY; 314 } 315 316 /* Hardware appends ICV. */ 317 plcp_fragment_len += info->control.hw_key->icv_len; 318 319 key_idx = b43_kidx_to_fw(dev, key_idx); 320 mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) & 321 B43_TXH_MAC_KEYIDX; 322 mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) & 323 B43_TXH_MAC_KEYALG; 324 wlhdr_len = ieee80211_hdrlen(fctl); 325 if (key->algorithm == B43_SEC_ALGO_TKIP) { 326 u16 phase1key[5]; 327 int i; 328 /* we give the phase1key and iv16 here, the key is stored in 329 * shm. With that the hardware can do phase 2 and encryption. 330 */ 331 ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key); 332 /* phase1key is in host endian. Copy to little-endian txhdr->iv. */ 333 for (i = 0; i < 5; i++) { 334 txhdr->iv[i * 2 + 0] = phase1key[i]; 335 txhdr->iv[i * 2 + 1] = phase1key[i] >> 8; 336 } 337 /* iv16 */ 338 memcpy(txhdr->iv + 10, ((u8 *) wlhdr) + wlhdr_len, 3); 339 } else { 340 iv_len = min((size_t) info->control.hw_key->iv_len, 341 ARRAY_SIZE(txhdr->iv)); 342 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len); 343 } 344 } 345 switch (dev->fw.hdr_format) { 346 case B43_FW_HDR_598: 347 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_598.plcp), 348 plcp_fragment_len, rate); 349 break; 350 case B43_FW_HDR_351: 351 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_351.plcp), 352 plcp_fragment_len, rate); 353 break; 354 case B43_FW_HDR_410: 355 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_410.plcp), 356 plcp_fragment_len, rate); 357 break; 358 } 359 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb), 360 plcp_fragment_len, rate_fb); 361 362 /* Extra Frame Types */ 363 if (rate_fb_ofdm) 364 extra_ft |= B43_TXH_EFT_FB_OFDM; 365 else 366 extra_ft |= B43_TXH_EFT_FB_CCK; 367 368 /* Set channel radio code. Note that the micrcode ORs 0x100 to 369 * this value before comparing it to the value in SHM, if this 370 * is a 5Ghz packet. 371 */ 372 txhdr->chan_radio_code = phy->channel; 373 374 /* PHY TX Control word */ 375 if (rate_ofdm) 376 phy_ctl |= B43_TXH_PHY_ENC_OFDM; 377 else 378 phy_ctl |= B43_TXH_PHY_ENC_CCK; 379 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) 380 phy_ctl |= B43_TXH_PHY_SHORTPRMBL; 381 382 switch (b43_ieee80211_antenna_sanitize(dev, 0)) { 383 case 0: /* Default */ 384 phy_ctl |= B43_TXH_PHY_ANT01AUTO; 385 break; 386 case 1: /* Antenna 0 */ 387 phy_ctl |= B43_TXH_PHY_ANT0; 388 break; 389 case 2: /* Antenna 1 */ 390 phy_ctl |= B43_TXH_PHY_ANT1; 391 break; 392 case 3: /* Antenna 2 */ 393 phy_ctl |= B43_TXH_PHY_ANT2; 394 break; 395 case 4: /* Antenna 3 */ 396 phy_ctl |= B43_TXH_PHY_ANT3; 397 break; 398 default: 399 B43_WARN_ON(1); 400 } 401 402 rates = info->control.rates; 403 /* MAC control */ 404 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 405 mac_ctl |= B43_TXH_MAC_ACK; 406 /* use hardware sequence counter as the non-TID counter */ 407 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) 408 mac_ctl |= B43_TXH_MAC_HWSEQ; 409 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) 410 mac_ctl |= B43_TXH_MAC_STMSDU; 411 if (phy->type == B43_PHYTYPE_A) 412 mac_ctl |= B43_TXH_MAC_5GHZ; 413 414 /* Overwrite rates[0].count to make the retry calculation 415 * in the tx status easier. need the actual retry limit to 416 * detect whether the fallback rate was used. 417 */ 418 if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || 419 (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) { 420 rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count; 421 mac_ctl |= B43_TXH_MAC_LONGFRAME; 422 } else { 423 rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count; 424 } 425 426 /* Generate the RTS or CTS-to-self frame */ 427 if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || 428 (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) { 429 unsigned int len; 430 struct ieee80211_hdr *uninitialized_var(hdr); 431 int rts_rate, rts_rate_fb; 432 int rts_rate_ofdm, rts_rate_fb_ofdm; 433 struct b43_plcp_hdr6 *uninitialized_var(plcp); 434 struct ieee80211_rate *rts_cts_rate; 435 436 rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info); 437 438 rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB; 439 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); 440 rts_rate_fb = b43_calc_fallback_rate(rts_rate); 441 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); 442 443 if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 444 struct ieee80211_cts *uninitialized_var(cts); 445 446 switch (dev->fw.hdr_format) { 447 case B43_FW_HDR_598: 448 cts = (struct ieee80211_cts *) 449 (txhdr->format_598.rts_frame); 450 break; 451 case B43_FW_HDR_351: 452 cts = (struct ieee80211_cts *) 453 (txhdr->format_351.rts_frame); 454 break; 455 case B43_FW_HDR_410: 456 cts = (struct ieee80211_cts *) 457 (txhdr->format_410.rts_frame); 458 break; 459 } 460 ieee80211_ctstoself_get(dev->wl->hw, info->control.vif, 461 fragment_data, fragment_len, 462 info, cts); 463 mac_ctl |= B43_TXH_MAC_SENDCTS; 464 len = sizeof(struct ieee80211_cts); 465 } else { 466 struct ieee80211_rts *uninitialized_var(rts); 467 468 switch (dev->fw.hdr_format) { 469 case B43_FW_HDR_598: 470 rts = (struct ieee80211_rts *) 471 (txhdr->format_598.rts_frame); 472 break; 473 case B43_FW_HDR_351: 474 rts = (struct ieee80211_rts *) 475 (txhdr->format_351.rts_frame); 476 break; 477 case B43_FW_HDR_410: 478 rts = (struct ieee80211_rts *) 479 (txhdr->format_410.rts_frame); 480 break; 481 } 482 ieee80211_rts_get(dev->wl->hw, info->control.vif, 483 fragment_data, fragment_len, 484 info, rts); 485 mac_ctl |= B43_TXH_MAC_SENDRTS; 486 len = sizeof(struct ieee80211_rts); 487 } 488 len += FCS_LEN; 489 490 /* Generate the PLCP headers for the RTS/CTS frame */ 491 switch (dev->fw.hdr_format) { 492 case B43_FW_HDR_598: 493 plcp = &txhdr->format_598.rts_plcp; 494 break; 495 case B43_FW_HDR_351: 496 plcp = &txhdr->format_351.rts_plcp; 497 break; 498 case B43_FW_HDR_410: 499 plcp = &txhdr->format_410.rts_plcp; 500 break; 501 } 502 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp, 503 len, rts_rate); 504 plcp = &txhdr->rts_plcp_fb; 505 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp, 506 len, rts_rate_fb); 507 508 switch (dev->fw.hdr_format) { 509 case B43_FW_HDR_598: 510 hdr = (struct ieee80211_hdr *) 511 (&txhdr->format_598.rts_frame); 512 break; 513 case B43_FW_HDR_351: 514 hdr = (struct ieee80211_hdr *) 515 (&txhdr->format_351.rts_frame); 516 break; 517 case B43_FW_HDR_410: 518 hdr = (struct ieee80211_hdr *) 519 (&txhdr->format_410.rts_frame); 520 break; 521 } 522 txhdr->rts_dur_fb = hdr->duration_id; 523 524 if (rts_rate_ofdm) { 525 extra_ft |= B43_TXH_EFT_RTS_OFDM; 526 txhdr->phy_rate_rts = 527 b43_plcp_get_ratecode_ofdm(rts_rate); 528 } else { 529 extra_ft |= B43_TXH_EFT_RTS_CCK; 530 txhdr->phy_rate_rts = 531 b43_plcp_get_ratecode_cck(rts_rate); 532 } 533 if (rts_rate_fb_ofdm) 534 extra_ft |= B43_TXH_EFT_RTSFB_OFDM; 535 else 536 extra_ft |= B43_TXH_EFT_RTSFB_CCK; 537 538 if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS && 539 fill_phy_ctl1) { 540 txhdr->phy_ctl1_rts = cpu_to_le16( 541 b43_generate_tx_phy_ctl1(dev, rts_rate)); 542 txhdr->phy_ctl1_rts_fb = cpu_to_le16( 543 b43_generate_tx_phy_ctl1(dev, rts_rate_fb)); 544 } 545 } 546 547 /* Magic cookie */ 548 switch (dev->fw.hdr_format) { 549 case B43_FW_HDR_598: 550 txhdr->format_598.cookie = cpu_to_le16(cookie); 551 break; 552 case B43_FW_HDR_351: 553 txhdr->format_351.cookie = cpu_to_le16(cookie); 554 break; 555 case B43_FW_HDR_410: 556 txhdr->format_410.cookie = cpu_to_le16(cookie); 557 break; 558 } 559 560 if (fill_phy_ctl1) { 561 txhdr->phy_ctl1 = 562 cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate)); 563 txhdr->phy_ctl1_fb = 564 cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate_fb)); 565 } 566 567 /* Apply the bitfields */ 568 txhdr->mac_ctl = cpu_to_le32(mac_ctl); 569 txhdr->phy_ctl = cpu_to_le16(phy_ctl); 570 txhdr->extra_ft = extra_ft; 571 572 return 0; 573} 574 575static s8 b43_rssi_postprocess(struct b43_wldev *dev, 576 u8 in_rssi, int ofdm, 577 int adjust_2053, int adjust_2050) 578{ 579 struct b43_phy *phy = &dev->phy; 580 struct b43_phy_g *gphy = phy->g; 581 s32 tmp; 582 583 switch (phy->radio_ver) { 584 case 0x2050: 585 if (ofdm) { 586 tmp = in_rssi; 587 if (tmp > 127) 588 tmp -= 256; 589 tmp *= 73; 590 tmp /= 64; 591 if (adjust_2050) 592 tmp += 25; 593 else 594 tmp -= 3; 595 } else { 596 if (dev->dev->bus_sprom-> 597 boardflags_lo & B43_BFL_RSSI) { 598 if (in_rssi > 63) 599 in_rssi = 63; 600 B43_WARN_ON(phy->type != B43_PHYTYPE_G); 601 tmp = gphy->nrssi_lt[in_rssi]; 602 tmp = 31 - tmp; 603 tmp *= -131; 604 tmp /= 128; 605 tmp -= 57; 606 } else { 607 tmp = in_rssi; 608 tmp = 31 - tmp; 609 tmp *= -149; 610 tmp /= 128; 611 tmp -= 68; 612 } 613 if (phy->type == B43_PHYTYPE_G && adjust_2050) 614 tmp += 25; 615 } 616 break; 617 case 0x2060: 618 if (in_rssi > 127) 619 tmp = in_rssi - 256; 620 else 621 tmp = in_rssi; 622 break; 623 default: 624 tmp = in_rssi; 625 tmp -= 11; 626 tmp *= 103; 627 tmp /= 64; 628 if (adjust_2053) 629 tmp -= 109; 630 else 631 tmp -= 83; 632 } 633 634 return (s8) tmp; 635} 636 637//TODO 638#if 0 639static s8 b43_rssinoise_postprocess(struct b43_wldev *dev, u8 in_rssi) 640{ 641 struct b43_phy *phy = &dev->phy; 642 s8 ret; 643 644 if (phy->type == B43_PHYTYPE_A) { 645 //TODO: Incomplete specs. 646 ret = 0; 647 } else 648 ret = b43_rssi_postprocess(dev, in_rssi, 0, 1, 1); 649 650 return ret; 651} 652#endif 653 654void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) 655{ 656 struct ieee80211_rx_status status; 657 struct b43_plcp_hdr6 *plcp; 658 struct ieee80211_hdr *wlhdr; 659 const struct b43_rxhdr_fw4 *rxhdr = _rxhdr; 660 __le16 fctl; 661 u16 phystat0, phystat3; 662 u16 uninitialized_var(chanstat), uninitialized_var(mactime); 663 u32 uninitialized_var(macstat); 664 u16 chanid; 665 u16 phytype; 666 int padding, rate_idx; 667 668 memset(&status, 0, sizeof(status)); 669 670 /* Get metadata about the frame from the header. */ 671 phystat0 = le16_to_cpu(rxhdr->phy_status0); 672 phystat3 = le16_to_cpu(rxhdr->phy_status3); 673 switch (dev->fw.hdr_format) { 674 case B43_FW_HDR_598: 675 macstat = le32_to_cpu(rxhdr->format_598.mac_status); 676 mactime = le16_to_cpu(rxhdr->format_598.mac_time); 677 chanstat = le16_to_cpu(rxhdr->format_598.channel); 678 break; 679 case B43_FW_HDR_410: 680 case B43_FW_HDR_351: 681 macstat = le32_to_cpu(rxhdr->format_351.mac_status); 682 mactime = le16_to_cpu(rxhdr->format_351.mac_time); 683 chanstat = le16_to_cpu(rxhdr->format_351.channel); 684 break; 685 } 686 phytype = chanstat & B43_RX_CHAN_PHYTYPE; 687 688 if (unlikely(macstat & B43_RX_MAC_FCSERR)) { 689 dev->wl->ieee_stats.dot11FCSErrorCount++; 690 status.flag |= RX_FLAG_FAILED_FCS_CRC; 691 } 692 if (unlikely(phystat0 & (B43_RX_PHYST0_PLCPHCF | B43_RX_PHYST0_PLCPFV))) 693 status.flag |= RX_FLAG_FAILED_PLCP_CRC; 694 if (phystat0 & B43_RX_PHYST0_SHORTPRMBL) 695 status.flag |= RX_FLAG_SHORTPRE; 696 if (macstat & B43_RX_MAC_DECERR) { 697 /* Decryption with the given key failed. 698 * Drop the packet. We also won't be able to decrypt it with 699 * the key in software. */ 700 goto drop; 701 } 702 703 /* Skip PLCP and padding */ 704 padding = (macstat & B43_RX_MAC_PADDING) ? 2 : 0; 705 if (unlikely(skb->len < (sizeof(struct b43_plcp_hdr6) + padding))) { 706 b43dbg(dev->wl, "RX: Packet size underrun (1)\n"); 707 goto drop; 708 } 709 plcp = (struct b43_plcp_hdr6 *)(skb->data + padding); 710 skb_pull(skb, sizeof(struct b43_plcp_hdr6) + padding); 711 /* The skb contains the Wireless Header + payload data now */ 712 if (unlikely(skb->len < (2 + 2 + 6 /*minimum hdr */ + FCS_LEN))) { 713 b43dbg(dev->wl, "RX: Packet size underrun (2)\n"); 714 goto drop; 715 } 716 wlhdr = (struct ieee80211_hdr *)(skb->data); 717 fctl = wlhdr->frame_control; 718 719 if (macstat & B43_RX_MAC_DEC) { 720 unsigned int keyidx; 721 int wlhdr_len; 722 723 keyidx = ((macstat & B43_RX_MAC_KEYIDX) 724 >> B43_RX_MAC_KEYIDX_SHIFT); 725 /* We must adjust the key index here. We want the "physical" 726 * key index, but the ucode passed it slightly different. 727 */ 728 keyidx = b43_kidx_to_raw(dev, keyidx); 729 B43_WARN_ON(keyidx >= ARRAY_SIZE(dev->key)); 730 731 if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) { 732 wlhdr_len = ieee80211_hdrlen(fctl); 733 if (unlikely(skb->len < (wlhdr_len + 3))) { 734 b43dbg(dev->wl, 735 "RX: Packet size underrun (3)\n"); 736 goto drop; 737 } 738 status.flag |= RX_FLAG_DECRYPTED; 739 } 740 } 741 742 /* Link quality statistics */ 743 switch (chanstat & B43_RX_CHAN_PHYTYPE) { 744 case B43_PHYTYPE_HT: 745 /* TODO: is max the right choice? */ 746 status.signal = max_t(__s8, 747 max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1), 748 rxhdr->phy_ht_power2); 749 break; 750 case B43_PHYTYPE_N: 751 /* Broadcom has code for min and avg, but always uses max */ 752 if (rxhdr->power0 == 16 || rxhdr->power0 == 32) 753 status.signal = max(rxhdr->power1, rxhdr->power2); 754 else 755 status.signal = max(rxhdr->power0, rxhdr->power1); 756 break; 757 case B43_PHYTYPE_A: 758 case B43_PHYTYPE_B: 759 case B43_PHYTYPE_G: 760 case B43_PHYTYPE_LP: 761 status.signal = b43_rssi_postprocess(dev, rxhdr->jssi, 762 (phystat0 & B43_RX_PHYST0_OFDM), 763 (phystat0 & B43_RX_PHYST0_GAINCTL), 764 (phystat3 & B43_RX_PHYST3_TRSTATE)); 765 break; 766 } 767 768 if (phystat0 & B43_RX_PHYST0_OFDM) 769 rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp, 770 phytype == B43_PHYTYPE_A); 771 else 772 rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); 773 if (unlikely(rate_idx == -1)) { 774 /* PLCP seems to be corrupted. 775 * Drop the frame, if we are not interested in corrupted frames. */ 776 if (!(dev->wl->filter_flags & FIF_PLCPFAIL)) 777 goto drop; 778 } 779 status.rate_idx = rate_idx; 780 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); 781 782 /* 783 * All frames on monitor interfaces and beacons always need a full 784 * 64-bit timestamp. Monitor interfaces need it for diagnostic 785 * purposes and beacons for IBSS merging. 786 * This code assumes we get to process the packet within 16 bits 787 * of timestamp, i.e. about 65 milliseconds after the PHY received 788 * the first symbol. 789 */ 790 if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) { 791 u16 low_mactime_now; 792 793 b43_tsf_read(dev, &status.mactime); 794 low_mactime_now = status.mactime; 795 status.mactime = status.mactime & ~0xFFFFULL; 796 status.mactime += mactime; 797 if (low_mactime_now <= mactime) 798 status.mactime -= 0x10000; 799 status.flag |= RX_FLAG_MACTIME_START; 800 } 801 802 chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; 803 switch (chanstat & B43_RX_CHAN_PHYTYPE) { 804 case B43_PHYTYPE_A: 805 status.band = IEEE80211_BAND_5GHZ; 806 B43_WARN_ON(1); 807 /* FIXME: We don't really know which value the "chanid" contains. 808 * So the following assignment might be wrong. */ 809 status.freq = b43_channel_to_freq_5ghz(chanid); 810 break; 811 case B43_PHYTYPE_G: 812 status.band = IEEE80211_BAND_2GHZ; 813 /* chanid is the radio channel cookie value as used 814 * to tune the radio. */ 815 status.freq = chanid + 2400; 816 break; 817 case B43_PHYTYPE_N: 818 case B43_PHYTYPE_LP: 819 case B43_PHYTYPE_HT: 820 /* chanid is the SHM channel cookie. Which is the plain 821 * channel number in b43. */ 822 if (chanstat & B43_RX_CHAN_5GHZ) { 823 status.band = IEEE80211_BAND_5GHZ; 824 status.freq = b43_freq_to_channel_5ghz(chanid); 825 } else { 826 status.band = IEEE80211_BAND_2GHZ; 827 status.freq = b43_freq_to_channel_2ghz(chanid); 828 } 829 break; 830 default: 831 B43_WARN_ON(1); 832 goto drop; 833 } 834 835 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); 836 ieee80211_rx_ni(dev->wl->hw, skb); 837 838#if B43_DEBUG 839 dev->rx_count++; 840#endif 841 return; 842drop: 843 dev_kfree_skb_any(skb); 844} 845 846void b43_handle_txstatus(struct b43_wldev *dev, 847 const struct b43_txstatus *status) 848{ 849 b43_debugfs_log_txstat(dev, status); 850 851 if (status->intermediate) 852 return; 853 if (status->for_ampdu) 854 return; 855 if (!status->acked) 856 dev->wl->ieee_stats.dot11ACKFailureCount++; 857 if (status->rts_count) { 858 if (status->rts_count == 0xF) //FIXME 859 dev->wl->ieee_stats.dot11RTSFailureCount++; 860 else 861 dev->wl->ieee_stats.dot11RTSSuccessCount++; 862 } 863 864 if (b43_using_pio_transfers(dev)) 865 b43_pio_handle_txstatus(dev, status); 866 else 867 b43_dma_handle_txstatus(dev, status); 868 869 b43_phy_txpower_check(dev, 0); 870} 871 872/* Fill out the mac80211 TXstatus report based on the b43-specific 873 * txstatus report data. This returns a boolean whether the frame was 874 * successfully transmitted. */ 875bool b43_fill_txstatus_report(struct b43_wldev *dev, 876 struct ieee80211_tx_info *report, 877 const struct b43_txstatus *status) 878{ 879 bool frame_success = true; 880 int retry_limit; 881 882 /* preserve the confiured retry limit before clearing the status 883 * The xmit function has overwritten the rc's value with the actual 884 * retry limit done by the hardware */ 885 retry_limit = report->status.rates[0].count; 886 ieee80211_tx_info_clear_status(report); 887 888 if (status->acked) { 889 /* The frame was ACKed. */ 890 report->flags |= IEEE80211_TX_STAT_ACK; 891 } else { 892 /* The frame was not ACKed... */ 893 if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) { 894 /* ...but we expected an ACK. */ 895 frame_success = false; 896 } 897 } 898 if (status->frame_count == 0) { 899 /* The frame was not transmitted at all. */ 900 report->status.rates[0].count = 0; 901 } else if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) { 902 /* 903 * If the short retries (RTS, not data frame) have exceeded 904 * the limit, the hw will not have tried the selected rate, 905 * but will have used the fallback rate instead. 906 * Don't let the rate control count attempts for the selected 907 * rate in this case, otherwise the statistics will be off. 908 */ 909 report->status.rates[0].count = 0; 910 report->status.rates[1].count = status->frame_count; 911 } else { 912 if (status->frame_count > retry_limit) { 913 report->status.rates[0].count = retry_limit; 914 report->status.rates[1].count = status->frame_count - 915 retry_limit; 916 917 } else { 918 report->status.rates[0].count = status->frame_count; 919 report->status.rates[1].idx = -1; 920 } 921 } 922 923 return frame_success; 924} 925 926/* Stop any TX operation on the device (suspend the hardware queues) */ 927void b43_tx_suspend(struct b43_wldev *dev) 928{ 929 if (b43_using_pio_transfers(dev)) 930 b43_pio_tx_suspend(dev); 931 else 932 b43_dma_tx_suspend(dev); 933} 934 935/* Resume any TX operation on the device (resume the hardware queues) */ 936void b43_tx_resume(struct b43_wldev *dev) 937{ 938 if (b43_using_pio_transfers(dev)) 939 b43_pio_tx_resume(dev); 940 else 941 b43_dma_tx_resume(dev); 942}