root/drivers/net/wireless/broadcom/b43/phy_common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. b43_phy_allocate
  2. b43_phy_free
  3. b43_phy_init
  4. b43_phy_exit
  5. b43_has_hardware_pctl
  6. b43_radio_lock
  7. b43_radio_unlock
  8. b43_phy_lock
  9. b43_phy_unlock
  10. assert_mac_suspended
  11. b43_radio_read
  12. b43_radio_write
  13. b43_radio_mask
  14. b43_radio_set
  15. b43_radio_maskset
  16. b43_radio_wait_value
  17. b43_phy_read
  18. b43_phy_write
  19. b43_phy_copy
  20. b43_phy_mask
  21. b43_phy_set
  22. b43_phy_maskset
  23. b43_phy_put_into_reset
  24. b43_phy_take_out_of_reset
  25. b43_switch_channel
  26. b43_software_rfkill
  27. b43_phy_txpower_adjust_work
  28. b43_phy_txpower_check
  29. b43_phy_shm_tssi_read
  30. b43_phyop_switch_analog_generic
  31. b43_is_40mhz
  32. b43_phy_force_clock

   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 }

/* [<][>][^][v][top][bottom][index][help] */