0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include "phy_common.h"
0017 #include "phy_g.h"
0018 #include "phy_a.h"
0019 #include "phy_n.h"
0020 #include "phy_lp.h"
0021 #include "phy_ht.h"
0022 #include "phy_lcn.h"
0023 #include "phy_ac.h"
0024 #include "b43.h"
0025 #include "main.h"
0026
0027
0028 int b43_phy_allocate(struct b43_wldev *dev)
0029 {
0030 struct b43_phy *phy = &(dev->phy);
0031 int err;
0032
0033 phy->ops = NULL;
0034
0035 switch (phy->type) {
0036 case B43_PHYTYPE_G:
0037 #ifdef CONFIG_B43_PHY_G
0038 phy->ops = &b43_phyops_g;
0039 #endif
0040 break;
0041 case B43_PHYTYPE_N:
0042 #ifdef CONFIG_B43_PHY_N
0043 phy->ops = &b43_phyops_n;
0044 #endif
0045 break;
0046 case B43_PHYTYPE_LP:
0047 #ifdef CONFIG_B43_PHY_LP
0048 phy->ops = &b43_phyops_lp;
0049 #endif
0050 break;
0051 case B43_PHYTYPE_HT:
0052 #ifdef CONFIG_B43_PHY_HT
0053 phy->ops = &b43_phyops_ht;
0054 #endif
0055 break;
0056 case B43_PHYTYPE_LCN:
0057 #ifdef CONFIG_B43_PHY_LCN
0058 phy->ops = &b43_phyops_lcn;
0059 #endif
0060 break;
0061 case B43_PHYTYPE_AC:
0062 #ifdef CONFIG_B43_PHY_AC
0063 phy->ops = &b43_phyops_ac;
0064 #endif
0065 break;
0066 }
0067 if (B43_WARN_ON(!phy->ops))
0068 return -ENODEV;
0069
0070 err = phy->ops->allocate(dev);
0071 if (err)
0072 phy->ops = NULL;
0073
0074 return err;
0075 }
0076
0077 void b43_phy_free(struct b43_wldev *dev)
0078 {
0079 dev->phy.ops->free(dev);
0080 dev->phy.ops = NULL;
0081 }
0082
0083 int b43_phy_init(struct b43_wldev *dev)
0084 {
0085 struct b43_phy *phy = &dev->phy;
0086 const struct b43_phy_operations *ops = phy->ops;
0087 int err;
0088
0089
0090
0091
0092 if (!phy->chandef) {
0093 phy->chandef = &dev->wl->hw->conf.chandef;
0094 phy->channel = phy->chandef->chan->hw_value;
0095 }
0096
0097 phy->ops->switch_analog(dev, true);
0098 b43_software_rfkill(dev, false);
0099
0100 err = ops->init(dev);
0101 if (err) {
0102 b43err(dev->wl, "PHY init failed\n");
0103 goto err_block_rf;
0104 }
0105 phy->do_full_init = false;
0106
0107 err = b43_switch_channel(dev, phy->channel);
0108 if (err) {
0109 b43err(dev->wl, "PHY init: Channel switch to default failed\n");
0110 goto err_phy_exit;
0111 }
0112
0113 return 0;
0114
0115 err_phy_exit:
0116 phy->do_full_init = true;
0117 if (ops->exit)
0118 ops->exit(dev);
0119 err_block_rf:
0120 b43_software_rfkill(dev, true);
0121
0122 return err;
0123 }
0124
0125 void b43_phy_exit(struct b43_wldev *dev)
0126 {
0127 const struct b43_phy_operations *ops = dev->phy.ops;
0128
0129 b43_software_rfkill(dev, true);
0130 dev->phy.do_full_init = true;
0131 if (ops->exit)
0132 ops->exit(dev);
0133 }
0134
0135 bool b43_has_hardware_pctl(struct b43_wldev *dev)
0136 {
0137 if (!dev->phy.hardware_power_control)
0138 return false;
0139 if (!dev->phy.ops->supports_hwpctl)
0140 return false;
0141 return dev->phy.ops->supports_hwpctl(dev);
0142 }
0143
0144 void b43_radio_lock(struct b43_wldev *dev)
0145 {
0146 u32 macctl;
0147
0148 #if B43_DEBUG
0149 B43_WARN_ON(dev->phy.radio_locked);
0150 dev->phy.radio_locked = true;
0151 #endif
0152
0153 macctl = b43_read32(dev, B43_MMIO_MACCTL);
0154 macctl |= B43_MACCTL_RADIOLOCK;
0155 b43_write32(dev, B43_MMIO_MACCTL, macctl);
0156
0157
0158 b43_read32(dev, B43_MMIO_MACCTL);
0159 udelay(10);
0160 }
0161
0162 void b43_radio_unlock(struct b43_wldev *dev)
0163 {
0164 u32 macctl;
0165
0166 #if B43_DEBUG
0167 B43_WARN_ON(!dev->phy.radio_locked);
0168 dev->phy.radio_locked = false;
0169 #endif
0170
0171
0172 b43_read16(dev, B43_MMIO_PHY_VER);
0173
0174 macctl = b43_read32(dev, B43_MMIO_MACCTL);
0175 macctl &= ~B43_MACCTL_RADIOLOCK;
0176 b43_write32(dev, B43_MMIO_MACCTL, macctl);
0177 }
0178
0179 void b43_phy_lock(struct b43_wldev *dev)
0180 {
0181 #if B43_DEBUG
0182 B43_WARN_ON(dev->phy.phy_locked);
0183 dev->phy.phy_locked = true;
0184 #endif
0185 B43_WARN_ON(dev->dev->core_rev < 3);
0186
0187 if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
0188 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
0189 }
0190
0191 void b43_phy_unlock(struct b43_wldev *dev)
0192 {
0193 #if B43_DEBUG
0194 B43_WARN_ON(!dev->phy.phy_locked);
0195 dev->phy.phy_locked = false;
0196 #endif
0197 B43_WARN_ON(dev->dev->core_rev < 3);
0198
0199 if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
0200 b43_power_saving_ctl_bits(dev, 0);
0201 }
0202
0203 static inline void assert_mac_suspended(struct b43_wldev *dev)
0204 {
0205 if (!B43_DEBUG)
0206 return;
0207 if ((b43_status(dev) >= B43_STAT_INITIALIZED) &&
0208 (dev->mac_suspended <= 0)) {
0209 b43dbg(dev->wl, "PHY/RADIO register access with "
0210 "enabled MAC.\n");
0211 dump_stack();
0212 }
0213 }
0214
0215 u16 b43_radio_read(struct b43_wldev *dev, u16 reg)
0216 {
0217 assert_mac_suspended(dev);
0218 dev->phy.writes_counter = 0;
0219 return dev->phy.ops->radio_read(dev, reg);
0220 }
0221
0222 void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
0223 {
0224 assert_mac_suspended(dev);
0225 if (b43_bus_host_is_pci(dev->dev) &&
0226 ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) {
0227 b43_read32(dev, B43_MMIO_MACCTL);
0228 dev->phy.writes_counter = 1;
0229 }
0230 dev->phy.ops->radio_write(dev, reg, value);
0231 }
0232
0233 void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask)
0234 {
0235 b43_radio_write16(dev, offset,
0236 b43_radio_read16(dev, offset) & mask);
0237 }
0238
0239 void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set)
0240 {
0241 b43_radio_write16(dev, offset,
0242 b43_radio_read16(dev, offset) | set);
0243 }
0244
0245 void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
0246 {
0247 b43_radio_write16(dev, offset,
0248 (b43_radio_read16(dev, offset) & mask) | set);
0249 }
0250
0251 bool b43_radio_wait_value(struct b43_wldev *dev, u16 offset, u16 mask,
0252 u16 value, int delay, int timeout)
0253 {
0254 u16 val;
0255 int i;
0256
0257 for (i = 0; i < timeout; i += delay) {
0258 val = b43_radio_read(dev, offset);
0259 if ((val & mask) == value)
0260 return true;
0261 udelay(delay);
0262 }
0263 return false;
0264 }
0265
0266 u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
0267 {
0268 assert_mac_suspended(dev);
0269 dev->phy.writes_counter = 0;
0270
0271 if (dev->phy.ops->phy_read)
0272 return dev->phy.ops->phy_read(dev, reg);
0273
0274 b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
0275 return b43_read16(dev, B43_MMIO_PHY_DATA);
0276 }
0277
0278 void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
0279 {
0280 assert_mac_suspended(dev);
0281 if (b43_bus_host_is_pci(dev->dev) &&
0282 ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) {
0283 b43_read16(dev, B43_MMIO_PHY_VER);
0284 dev->phy.writes_counter = 1;
0285 }
0286
0287 if (dev->phy.ops->phy_write)
0288 return dev->phy.ops->phy_write(dev, reg, value);
0289
0290 b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
0291 b43_write16(dev, B43_MMIO_PHY_DATA, value);
0292 }
0293
0294 void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
0295 {
0296 b43_phy_write(dev, destreg, b43_phy_read(dev, srcreg));
0297 }
0298
0299 void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
0300 {
0301 if (dev->phy.ops->phy_maskset) {
0302 assert_mac_suspended(dev);
0303 dev->phy.ops->phy_maskset(dev, offset, mask, 0);
0304 } else {
0305 b43_phy_write(dev, offset,
0306 b43_phy_read(dev, offset) & mask);
0307 }
0308 }
0309
0310 void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set)
0311 {
0312 if (dev->phy.ops->phy_maskset) {
0313 assert_mac_suspended(dev);
0314 dev->phy.ops->phy_maskset(dev, offset, 0xFFFF, set);
0315 } else {
0316 b43_phy_write(dev, offset,
0317 b43_phy_read(dev, offset) | set);
0318 }
0319 }
0320
0321 void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
0322 {
0323 if (dev->phy.ops->phy_maskset) {
0324 assert_mac_suspended(dev);
0325 dev->phy.ops->phy_maskset(dev, offset, mask, set);
0326 } else {
0327 b43_phy_write(dev, offset,
0328 (b43_phy_read(dev, offset) & mask) | set);
0329 }
0330 }
0331
0332 void b43_phy_put_into_reset(struct b43_wldev *dev)
0333 {
0334 u32 tmp;
0335
0336 switch (dev->dev->bus_type) {
0337 #ifdef CONFIG_B43_BCMA
0338 case B43_BUS_BCMA:
0339 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
0340 tmp &= ~B43_BCMA_IOCTL_GMODE;
0341 tmp |= B43_BCMA_IOCTL_PHY_RESET;
0342 tmp |= BCMA_IOCTL_FGC;
0343 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
0344 udelay(1);
0345
0346 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
0347 tmp &= ~BCMA_IOCTL_FGC;
0348 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
0349 udelay(1);
0350 break;
0351 #endif
0352 #ifdef CONFIG_B43_SSB
0353 case B43_BUS_SSB:
0354 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
0355 tmp &= ~B43_TMSLOW_GMODE;
0356 tmp |= B43_TMSLOW_PHYRESET;
0357 tmp |= SSB_TMSLOW_FGC;
0358 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
0359 usleep_range(1000, 2000);
0360
0361 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
0362 tmp &= ~SSB_TMSLOW_FGC;
0363 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
0364 usleep_range(1000, 2000);
0365
0366 break;
0367 #endif
0368 }
0369 }
0370
0371 void b43_phy_take_out_of_reset(struct b43_wldev *dev)
0372 {
0373 u32 tmp;
0374
0375 switch (dev->dev->bus_type) {
0376 #ifdef CONFIG_B43_BCMA
0377 case B43_BUS_BCMA:
0378
0379 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
0380 tmp &= ~B43_BCMA_IOCTL_PHY_RESET;
0381 tmp &= ~B43_BCMA_IOCTL_PHY_CLKEN;
0382 tmp |= BCMA_IOCTL_FGC;
0383 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
0384 udelay(1);
0385
0386
0387 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
0388 tmp &= ~BCMA_IOCTL_FGC;
0389 tmp |= B43_BCMA_IOCTL_PHY_CLKEN;
0390 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
0391 udelay(1);
0392 break;
0393 #endif
0394 #ifdef CONFIG_B43_SSB
0395 case B43_BUS_SSB:
0396
0397 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
0398 tmp &= ~B43_TMSLOW_PHYRESET;
0399 tmp &= ~B43_TMSLOW_PHYCLKEN;
0400 tmp |= SSB_TMSLOW_FGC;
0401 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
0402 ssb_read32(dev->dev->sdev, SSB_TMSLOW);
0403 usleep_range(1000, 2000);
0404
0405 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
0406 tmp &= ~SSB_TMSLOW_FGC;
0407 tmp |= B43_TMSLOW_PHYCLKEN;
0408 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
0409 ssb_read32(dev->dev->sdev, SSB_TMSLOW);
0410 usleep_range(1000, 2000);
0411 break;
0412 #endif
0413 }
0414 }
0415
0416 int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
0417 {
0418 struct b43_phy *phy = &(dev->phy);
0419 u16 channelcookie, savedcookie;
0420 int err;
0421
0422
0423
0424
0425 channelcookie = new_channel;
0426 if (b43_current_band(dev->wl) == NL80211_BAND_5GHZ)
0427 channelcookie |= B43_SHM_SH_CHAN_5GHZ;
0428
0429 if (0)
0430 channelcookie |= B43_SHM_SH_CHAN_40MHZ;
0431 savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN);
0432 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie);
0433
0434
0435 err = phy->ops->switch_channel(dev, new_channel);
0436 if (err)
0437 goto err_restore_cookie;
0438
0439
0440 msleep(8);
0441
0442 return 0;
0443
0444 err_restore_cookie:
0445 b43_shm_write16(dev, B43_SHM_SHARED,
0446 B43_SHM_SH_CHAN, savedcookie);
0447
0448 return err;
0449 }
0450
0451 void b43_software_rfkill(struct b43_wldev *dev, bool blocked)
0452 {
0453 struct b43_phy *phy = &dev->phy;
0454
0455 b43_mac_suspend(dev);
0456 phy->ops->software_rfkill(dev, blocked);
0457 phy->radio_on = !blocked;
0458 b43_mac_enable(dev);
0459 }
0460
0461
0462
0463
0464
0465
0466 void b43_phy_txpower_adjust_work(struct work_struct *work)
0467 {
0468 struct b43_wl *wl = container_of(work, struct b43_wl,
0469 txpower_adjust_work);
0470 struct b43_wldev *dev;
0471
0472 mutex_lock(&wl->mutex);
0473 dev = wl->current_dev;
0474
0475 if (likely(dev && (b43_status(dev) >= B43_STAT_STARTED)))
0476 dev->phy.ops->adjust_txpower(dev);
0477
0478 mutex_unlock(&wl->mutex);
0479 }
0480
0481 void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
0482 {
0483 struct b43_phy *phy = &dev->phy;
0484 unsigned long now = jiffies;
0485 enum b43_txpwr_result result;
0486
0487 if (!(flags & B43_TXPWR_IGNORE_TIME)) {
0488
0489 if (time_before(now, phy->next_txpwr_check_time))
0490 return;
0491 }
0492
0493 phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2));
0494
0495 if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
0496 (dev->dev->board_type == SSB_BOARD_BU4306))
0497 return;
0498
0499 result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI));
0500 if (result == B43_TXPWR_RES_DONE)
0501 return;
0502 B43_WARN_ON(result != B43_TXPWR_RES_NEED_ADJUST);
0503 B43_WARN_ON(phy->ops->adjust_txpower == NULL);
0504
0505
0506
0507 ieee80211_queue_work(dev->wl->hw, &dev->wl->txpower_adjust_work);
0508 }
0509
0510 int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset)
0511 {
0512 const bool is_ofdm = (shm_offset != B43_SHM_SH_TSSI_CCK);
0513 unsigned int a, b, c, d;
0514 unsigned int average;
0515 u32 tmp;
0516
0517 tmp = b43_shm_read32(dev, B43_SHM_SHARED, shm_offset);
0518 a = tmp & 0xFF;
0519 b = (tmp >> 8) & 0xFF;
0520 c = (tmp >> 16) & 0xFF;
0521 d = (tmp >> 24) & 0xFF;
0522 if (a == 0 || a == B43_TSSI_MAX ||
0523 b == 0 || b == B43_TSSI_MAX ||
0524 c == 0 || c == B43_TSSI_MAX ||
0525 d == 0 || d == B43_TSSI_MAX)
0526 return -ENOENT;
0527
0528 tmp = B43_TSSI_MAX | (B43_TSSI_MAX << 8) |
0529 (B43_TSSI_MAX << 16) | (B43_TSSI_MAX << 24);
0530 b43_shm_write32(dev, B43_SHM_SHARED, shm_offset, tmp);
0531
0532 if (is_ofdm) {
0533 a = (a + 32) & 0x3F;
0534 b = (b + 32) & 0x3F;
0535 c = (c + 32) & 0x3F;
0536 d = (d + 32) & 0x3F;
0537 }
0538
0539
0540 average = (a + b + c + d + 2) / 4;
0541 if (is_ofdm) {
0542
0543 if (b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF1)
0544 & B43_HF_CCKBOOST)
0545 average = (average >= 13) ? (average - 13) : 0;
0546 }
0547
0548 return average;
0549 }
0550
0551 void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
0552 {
0553 b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
0554 }
0555
0556
0557 bool b43_is_40mhz(struct b43_wldev *dev)
0558 {
0559 return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
0560 }
0561
0562
0563 void b43_phy_force_clock(struct b43_wldev *dev, bool force)
0564 {
0565 u32 tmp;
0566
0567 WARN_ON(dev->phy.type != B43_PHYTYPE_N &&
0568 dev->phy.type != B43_PHYTYPE_HT &&
0569 dev->phy.type != B43_PHYTYPE_AC);
0570
0571 switch (dev->dev->bus_type) {
0572 #ifdef CONFIG_B43_BCMA
0573 case B43_BUS_BCMA:
0574 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
0575 if (force)
0576 tmp |= BCMA_IOCTL_FGC;
0577 else
0578 tmp &= ~BCMA_IOCTL_FGC;
0579 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
0580 break;
0581 #endif
0582 #ifdef CONFIG_B43_SSB
0583 case B43_BUS_SSB:
0584 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
0585 if (force)
0586 tmp |= SSB_TMSLOW_FGC;
0587 else
0588 tmp &= ~SSB_TMSLOW_FGC;
0589 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
0590 break;
0591 #endif
0592 }
0593 }