1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 4 Broadcom B43 wireless driver 5 Common PHY routines 6 7 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, 8 Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it> 9 Copyright (c) 2005-2008 Michael Buesch <m@bues.ch> 10 Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org> 11 Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch> 12 13 14 */ 15 16 #include "phy_common.h" 17 #include "phy_g.h" 18 #include "phy_a.h" 19 #include "phy_n.h" 20 #include "phy_lp.h" 21 #include "phy_ht.h" 22 #include "phy_lcn.h" 23 #include "phy_ac.h" 24 #include "b43.h" 25 #include "main.h" 26 27 28 int b43_phy_allocate(struct b43_wldev *dev) 29 { 30 struct b43_phy *phy = &(dev->phy); 31 int err; 32 33 phy->ops = NULL; 34 35 switch (phy->type) { 36 case B43_PHYTYPE_G: 37 #ifdef CONFIG_B43_PHY_G 38 phy->ops = &b43_phyops_g; 39 #endif 40 break; 41 case B43_PHYTYPE_N: 42 #ifdef CONFIG_B43_PHY_N 43 phy->ops = &b43_phyops_n; 44 #endif 45 break; 46 case B43_PHYTYPE_LP: 47 #ifdef CONFIG_B43_PHY_LP 48 phy->ops = &b43_phyops_lp; 49 #endif 50 break; 51 case B43_PHYTYPE_HT: 52 #ifdef CONFIG_B43_PHY_HT 53 phy->ops = &b43_phyops_ht; 54 #endif 55 break; 56 case B43_PHYTYPE_LCN: 57 #ifdef CONFIG_B43_PHY_LCN 58 phy->ops = &b43_phyops_lcn; 59 #endif 60 break; 61 case B43_PHYTYPE_AC: 62 #ifdef CONFIG_B43_PHY_AC 63 phy->ops = &b43_phyops_ac; 64 #endif 65 break; 66 } 67 if (B43_WARN_ON(!phy->ops)) 68 return -ENODEV; 69 70 err = phy->ops->allocate(dev); 71 if (err) 72 phy->ops = NULL; 73 74 return err; 75 } 76 77 void b43_phy_free(struct b43_wldev *dev) 78 { 79 dev->phy.ops->free(dev); 80 dev->phy.ops = NULL; 81 } 82 83 int b43_phy_init(struct b43_wldev *dev) 84 { 85 struct b43_phy *phy = &dev->phy; 86 const struct b43_phy_operations *ops = phy->ops; 87 int err; 88 89 /* During PHY init we need to use some channel. On the first init this 90 * function is called *before* b43_op_config, so our pointer is NULL. 91 */ 92 if (!phy->chandef) { 93 phy->chandef = &dev->wl->hw->conf.chandef; 94 phy->channel = phy->chandef->chan->hw_value; 95 } 96 97 phy->ops->switch_analog(dev, true); 98 b43_software_rfkill(dev, false); 99 100 err = ops->init(dev); 101 if (err) { 102 b43err(dev->wl, "PHY init failed\n"); 103 goto err_block_rf; 104 } 105 phy->do_full_init = false; 106 107 err = b43_switch_channel(dev, phy->channel); 108 if (err) { 109 b43err(dev->wl, "PHY init: Channel switch to default failed\n"); 110 goto err_phy_exit; 111 } 112 113 return 0; 114 115 err_phy_exit: 116 phy->do_full_init = true; 117 if (ops->exit) 118 ops->exit(dev); 119 err_block_rf: 120 b43_software_rfkill(dev, true); 121 122 return err; 123 } 124 125 void b43_phy_exit(struct b43_wldev *dev) 126 { 127 const struct b43_phy_operations *ops = dev->phy.ops; 128 129 b43_software_rfkill(dev, true); 130 dev->phy.do_full_init = true; 131 if (ops->exit) 132 ops->exit(dev); 133 } 134 135 bool b43_has_hardware_pctl(struct b43_wldev *dev) 136 { 137 if (!dev->phy.hardware_power_control) 138 return false; 139 if (!dev->phy.ops->supports_hwpctl) 140 return false; 141 return dev->phy.ops->supports_hwpctl(dev); 142 } 143 144 void b43_radio_lock(struct b43_wldev *dev) 145 { 146 u32 macctl; 147 148 #if B43_DEBUG 149 B43_WARN_ON(dev->phy.radio_locked); 150 dev->phy.radio_locked = true; 151 #endif 152 153 macctl = b43_read32(dev, B43_MMIO_MACCTL); 154 macctl |= B43_MACCTL_RADIOLOCK; 155 b43_write32(dev, B43_MMIO_MACCTL, macctl); 156 /* Commit the write and wait for the firmware 157 * to finish any radio register access. */ 158 b43_read32(dev, B43_MMIO_MACCTL); 159 udelay(10); 160 } 161 162 void b43_radio_unlock(struct b43_wldev *dev) 163 { 164 u32 macctl; 165 166 #if B43_DEBUG 167 B43_WARN_ON(!dev->phy.radio_locked); 168 dev->phy.radio_locked = false; 169 #endif 170 171 /* Commit any write */ 172 b43_read16(dev, B43_MMIO_PHY_VER); 173 /* unlock */ 174 macctl = b43_read32(dev, B43_MMIO_MACCTL); 175 macctl &= ~B43_MACCTL_RADIOLOCK; 176 b43_write32(dev, B43_MMIO_MACCTL, macctl); 177 } 178 179 void b43_phy_lock(struct b43_wldev *dev) 180 { 181 #if B43_DEBUG 182 B43_WARN_ON(dev->phy.phy_locked); 183 dev->phy.phy_locked = true; 184 #endif 185 B43_WARN_ON(dev->dev->core_rev < 3); 186 187 if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) 188 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); 189 } 190 191 void b43_phy_unlock(struct b43_wldev *dev) 192 { 193 #if B43_DEBUG 194 B43_WARN_ON(!dev->phy.phy_locked); 195 dev->phy.phy_locked = false; 196 #endif 197 B43_WARN_ON(dev->dev->core_rev < 3); 198 199 if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) 200 b43_power_saving_ctl_bits(dev, 0); 201 } 202 203 static inline void assert_mac_suspended(struct b43_wldev *dev) 204 { 205 if (!B43_DEBUG) 206 return; 207 if ((b43_status(dev) >= B43_STAT_INITIALIZED) && 208 (dev->mac_suspended <= 0)) { 209 b43dbg(dev->wl, "PHY/RADIO register access with " 210 "enabled MAC.\n"); 211 dump_stack(); 212 } 213 } 214 215 u16 b43_radio_read(struct b43_wldev *dev, u16 reg) 216 { 217 assert_mac_suspended(dev); 218 dev->phy.writes_counter = 0; 219 return dev->phy.ops->radio_read(dev, reg); 220 } 221 222 void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value) 223 { 224 assert_mac_suspended(dev); 225 if (b43_bus_host_is_pci(dev->dev) && 226 ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) { 227 b43_read32(dev, B43_MMIO_MACCTL); 228 dev->phy.writes_counter = 1; 229 } 230 dev->phy.ops->radio_write(dev, reg, value); 231 } 232 233 void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask) 234 { 235 b43_radio_write16(dev, offset, 236 b43_radio_read16(dev, offset) & mask); 237 } 238 239 void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set) 240 { 241 b43_radio_write16(dev, offset, 242 b43_radio_read16(dev, offset) | set); 243 } 244 245 void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set) 246 { 247 b43_radio_write16(dev, offset, 248 (b43_radio_read16(dev, offset) & mask) | set); 249 } 250 251 bool b43_radio_wait_value(struct b43_wldev *dev, u16 offset, u16 mask, 252 u16 value, int delay, int timeout) 253 { 254 u16 val; 255 int i; 256 257 for (i = 0; i < timeout; i += delay) { 258 val = b43_radio_read(dev, offset); 259 if ((val & mask) == value) 260 return true; 261 udelay(delay); 262 } 263 return false; 264 } 265 266 u16 b43_phy_read(struct b43_wldev *dev, u16 reg) 267 { 268 assert_mac_suspended(dev); 269 dev->phy.writes_counter = 0; 270 271 if (dev->phy.ops->phy_read) 272 return dev->phy.ops->phy_read(dev, reg); 273 274 b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); 275 return b43_read16(dev, B43_MMIO_PHY_DATA); 276 } 277 278 void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value) 279 { 280 assert_mac_suspended(dev); 281 if (b43_bus_host_is_pci(dev->dev) && 282 ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) { 283 b43_read16(dev, B43_MMIO_PHY_VER); 284 dev->phy.writes_counter = 1; 285 } 286 287 if (dev->phy.ops->phy_write) 288 return dev->phy.ops->phy_write(dev, reg, value); 289 290 b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg); 291 b43_write16(dev, B43_MMIO_PHY_DATA, value); 292 } 293 294 void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg) 295 { 296 b43_phy_write(dev, destreg, b43_phy_read(dev, srcreg)); 297 } 298 299 void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask) 300 { 301 if (dev->phy.ops->phy_maskset) { 302 assert_mac_suspended(dev); 303 dev->phy.ops->phy_maskset(dev, offset, mask, 0); 304 } else { 305 b43_phy_write(dev, offset, 306 b43_phy_read(dev, offset) & mask); 307 } 308 } 309 310 void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set) 311 { 312 if (dev->phy.ops->phy_maskset) { 313 assert_mac_suspended(dev); 314 dev->phy.ops->phy_maskset(dev, offset, 0xFFFF, set); 315 } else { 316 b43_phy_write(dev, offset, 317 b43_phy_read(dev, offset) | set); 318 } 319 } 320 321 void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set) 322 { 323 if (dev->phy.ops->phy_maskset) { 324 assert_mac_suspended(dev); 325 dev->phy.ops->phy_maskset(dev, offset, mask, set); 326 } else { 327 b43_phy_write(dev, offset, 328 (b43_phy_read(dev, offset) & mask) | set); 329 } 330 } 331 332 void b43_phy_put_into_reset(struct b43_wldev *dev) 333 { 334 u32 tmp; 335 336 switch (dev->dev->bus_type) { 337 #ifdef CONFIG_B43_BCMA 338 case B43_BUS_BCMA: 339 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); 340 tmp &= ~B43_BCMA_IOCTL_GMODE; 341 tmp |= B43_BCMA_IOCTL_PHY_RESET; 342 tmp |= BCMA_IOCTL_FGC; 343 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); 344 udelay(1); 345 346 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); 347 tmp &= ~BCMA_IOCTL_FGC; 348 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); 349 udelay(1); 350 break; 351 #endif 352 #ifdef CONFIG_B43_SSB 353 case B43_BUS_SSB: 354 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); 355 tmp &= ~B43_TMSLOW_GMODE; 356 tmp |= B43_TMSLOW_PHYRESET; 357 tmp |= SSB_TMSLOW_FGC; 358 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); 359 usleep_range(1000, 2000); 360 361 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); 362 tmp &= ~SSB_TMSLOW_FGC; 363 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); 364 usleep_range(1000, 2000); 365 366 break; 367 #endif 368 } 369 } 370 371 void b43_phy_take_out_of_reset(struct b43_wldev *dev) 372 { 373 u32 tmp; 374 375 switch (dev->dev->bus_type) { 376 #ifdef CONFIG_B43_BCMA 377 case B43_BUS_BCMA: 378 /* Unset reset bit (with forcing clock) */ 379 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); 380 tmp &= ~B43_BCMA_IOCTL_PHY_RESET; 381 tmp &= ~B43_BCMA_IOCTL_PHY_CLKEN; 382 tmp |= BCMA_IOCTL_FGC; 383 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); 384 udelay(1); 385 386 /* Do not force clock anymore */ 387 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); 388 tmp &= ~BCMA_IOCTL_FGC; 389 tmp |= B43_BCMA_IOCTL_PHY_CLKEN; 390 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); 391 udelay(1); 392 break; 393 #endif 394 #ifdef CONFIG_B43_SSB 395 case B43_BUS_SSB: 396 /* Unset reset bit (with forcing clock) */ 397 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); 398 tmp &= ~B43_TMSLOW_PHYRESET; 399 tmp &= ~B43_TMSLOW_PHYCLKEN; 400 tmp |= SSB_TMSLOW_FGC; 401 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); 402 ssb_read32(dev->dev->sdev, SSB_TMSLOW); /* flush */ 403 usleep_range(1000, 2000); 404 405 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); 406 tmp &= ~SSB_TMSLOW_FGC; 407 tmp |= B43_TMSLOW_PHYCLKEN; 408 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); 409 ssb_read32(dev->dev->sdev, SSB_TMSLOW); /* flush */ 410 usleep_range(1000, 2000); 411 break; 412 #endif 413 } 414 } 415 416 int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel) 417 { 418 struct b43_phy *phy = &(dev->phy); 419 u16 channelcookie, savedcookie; 420 int err; 421 422 /* First we set the channel radio code to prevent the 423 * firmware from sending ghost packets. 424 */ 425 channelcookie = new_channel; 426 if (b43_current_band(dev->wl) == NL80211_BAND_5GHZ) 427 channelcookie |= B43_SHM_SH_CHAN_5GHZ; 428 /* FIXME: set 40Mhz flag if required */ 429 if (0) 430 channelcookie |= B43_SHM_SH_CHAN_40MHZ; 431 savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN); 432 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie); 433 434 /* Now try to switch the PHY hardware channel. */ 435 err = phy->ops->switch_channel(dev, new_channel); 436 if (err) 437 goto err_restore_cookie; 438 439 /* Wait for the radio to tune to the channel and stabilize. */ 440 msleep(8); 441 442 return 0; 443 444 err_restore_cookie: 445 b43_shm_write16(dev, B43_SHM_SHARED, 446 B43_SHM_SH_CHAN, savedcookie); 447 448 return err; 449 } 450 451 void b43_software_rfkill(struct b43_wldev *dev, bool blocked) 452 { 453 struct b43_phy *phy = &dev->phy; 454 455 b43_mac_suspend(dev); 456 phy->ops->software_rfkill(dev, blocked); 457 phy->radio_on = !blocked; 458 b43_mac_enable(dev); 459 } 460 461 /** 462 * b43_phy_txpower_adjust_work - TX power workqueue. 463 * 464 * Workqueue for updating the TX power parameters in hardware. 465 */ 466 void b43_phy_txpower_adjust_work(struct work_struct *work) 467 { 468 struct b43_wl *wl = container_of(work, struct b43_wl, 469 txpower_adjust_work); 470 struct b43_wldev *dev; 471 472 mutex_lock(&wl->mutex); 473 dev = wl->current_dev; 474 475 if (likely(dev && (b43_status(dev) >= B43_STAT_STARTED))) 476 dev->phy.ops->adjust_txpower(dev); 477 478 mutex_unlock(&wl->mutex); 479 } 480 481 void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags) 482 { 483 struct b43_phy *phy = &dev->phy; 484 unsigned long now = jiffies; 485 enum b43_txpwr_result result; 486 487 if (!(flags & B43_TXPWR_IGNORE_TIME)) { 488 /* Check if it's time for a TXpower check. */ 489 if (time_before(now, phy->next_txpwr_check_time)) 490 return; /* Not yet */ 491 } 492 /* The next check will be needed in two seconds, or later. */ 493 phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); 494 495 if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && 496 (dev->dev->board_type == SSB_BOARD_BU4306)) 497 return; /* No software txpower adjustment needed */ 498 499 result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); 500 if (result == B43_TXPWR_RES_DONE) 501 return; /* We are done. */ 502 B43_WARN_ON(result != B43_TXPWR_RES_NEED_ADJUST); 503 B43_WARN_ON(phy->ops->adjust_txpower == NULL); 504 505 /* We must adjust the transmission power in hardware. 506 * Schedule b43_phy_txpower_adjust_work(). */ 507 ieee80211_queue_work(dev->wl->hw, &dev->wl->txpower_adjust_work); 508 } 509 510 int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset) 511 { 512 const bool is_ofdm = (shm_offset != B43_SHM_SH_TSSI_CCK); 513 unsigned int a, b, c, d; 514 unsigned int average; 515 u32 tmp; 516 517 tmp = b43_shm_read32(dev, B43_SHM_SHARED, shm_offset); 518 a = tmp & 0xFF; 519 b = (tmp >> 8) & 0xFF; 520 c = (tmp >> 16) & 0xFF; 521 d = (tmp >> 24) & 0xFF; 522 if (a == 0 || a == B43_TSSI_MAX || 523 b == 0 || b == B43_TSSI_MAX || 524 c == 0 || c == B43_TSSI_MAX || 525 d == 0 || d == B43_TSSI_MAX) 526 return -ENOENT; 527 /* The values are OK. Clear them. */ 528 tmp = B43_TSSI_MAX | (B43_TSSI_MAX << 8) | 529 (B43_TSSI_MAX << 16) | (B43_TSSI_MAX << 24); 530 b43_shm_write32(dev, B43_SHM_SHARED, shm_offset, tmp); 531 532 if (is_ofdm) { 533 a = (a + 32) & 0x3F; 534 b = (b + 32) & 0x3F; 535 c = (c + 32) & 0x3F; 536 d = (d + 32) & 0x3F; 537 } 538 539 /* Get the average of the values with 0.5 added to each value. */ 540 average = (a + b + c + d + 2) / 4; 541 if (is_ofdm) { 542 /* Adjust for CCK-boost */ 543 if (b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF1) 544 & B43_HF_CCKBOOST) 545 average = (average >= 13) ? (average - 13) : 0; 546 } 547 548 return average; 549 } 550 551 void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on) 552 { 553 b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); 554 } 555 556 557 bool b43_is_40mhz(struct b43_wldev *dev) 558 { 559 return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40; 560 } 561 562 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */ 563 void b43_phy_force_clock(struct b43_wldev *dev, bool force) 564 { 565 u32 tmp; 566 567 WARN_ON(dev->phy.type != B43_PHYTYPE_N && 568 dev->phy.type != B43_PHYTYPE_HT && 569 dev->phy.type != B43_PHYTYPE_AC); 570 571 switch (dev->dev->bus_type) { 572 #ifdef CONFIG_B43_BCMA 573 case B43_BUS_BCMA: 574 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); 575 if (force) 576 tmp |= BCMA_IOCTL_FGC; 577 else 578 tmp &= ~BCMA_IOCTL_FGC; 579 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); 580 break; 581 #endif 582 #ifdef CONFIG_B43_SSB 583 case B43_BUS_SSB: 584 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); 585 if (force) 586 tmp |= SSB_TMSLOW_FGC; 587 else 588 tmp &= ~SSB_TMSLOW_FGC; 589 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); 590 break; 591 #endif 592 } 593 } 594