aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c149
1 files changed, 118 insertions, 31 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 15aaeb132a32..d7055febe119 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -210,6 +210,9 @@ static struct ieee80211_channel b43_2ghz_chantable[] = {
210 CHAN2G(13, 2472, 0), 210 CHAN2G(13, 2472, 0),
211 CHAN2G(14, 2484, 0), 211 CHAN2G(14, 2484, 0),
212}; 212};
213
214/* No support for the last 3 channels (12, 13, 14) */
215#define b43_2ghz_chantable_limited_size 11
213#undef CHAN2G 216#undef CHAN2G
214 217
215#define CHAN4G(_channel, _flags) { \ 218#define CHAN4G(_channel, _flags) { \
@@ -287,6 +290,14 @@ static struct ieee80211_channel b43_5ghz_nphy_chantable[] = {
287 CHAN5G(182, 0), 290 CHAN5G(182, 0),
288}; 291};
289 292
293static struct ieee80211_channel b43_5ghz_nphy_chantable_limited[] = {
294 CHAN5G(36, 0), CHAN5G(40, 0),
295 CHAN5G(44, 0), CHAN5G(48, 0),
296 CHAN5G(149, 0), CHAN5G(153, 0),
297 CHAN5G(157, 0), CHAN5G(161, 0),
298 CHAN5G(165, 0),
299};
300
290static struct ieee80211_channel b43_5ghz_aphy_chantable[] = { 301static struct ieee80211_channel b43_5ghz_aphy_chantable[] = {
291 CHAN5G(34, 0), CHAN5G(36, 0), 302 CHAN5G(34, 0), CHAN5G(36, 0),
292 CHAN5G(38, 0), CHAN5G(40, 0), 303 CHAN5G(38, 0), CHAN5G(40, 0),
@@ -319,6 +330,14 @@ static struct ieee80211_supported_band b43_band_5GHz_nphy = {
319 .n_bitrates = b43_a_ratetable_size, 330 .n_bitrates = b43_a_ratetable_size,
320}; 331};
321 332
333static struct ieee80211_supported_band b43_band_5GHz_nphy_limited = {
334 .band = IEEE80211_BAND_5GHZ,
335 .channels = b43_5ghz_nphy_chantable_limited,
336 .n_channels = ARRAY_SIZE(b43_5ghz_nphy_chantable_limited),
337 .bitrates = b43_a_ratetable,
338 .n_bitrates = b43_a_ratetable_size,
339};
340
322static struct ieee80211_supported_band b43_band_5GHz_aphy = { 341static struct ieee80211_supported_band b43_band_5GHz_aphy = {
323 .band = IEEE80211_BAND_5GHZ, 342 .band = IEEE80211_BAND_5GHZ,
324 .channels = b43_5ghz_aphy_chantable, 343 .channels = b43_5ghz_aphy_chantable,
@@ -335,6 +354,14 @@ static struct ieee80211_supported_band b43_band_2GHz = {
335 .n_bitrates = b43_g_ratetable_size, 354 .n_bitrates = b43_g_ratetable_size,
336}; 355};
337 356
357static struct ieee80211_supported_band b43_band_2ghz_limited = {
358 .band = IEEE80211_BAND_2GHZ,
359 .channels = b43_2ghz_chantable,
360 .n_channels = b43_2ghz_chantable_limited_size,
361 .bitrates = b43_g_ratetable,
362 .n_bitrates = b43_g_ratetable_size,
363};
364
338static void b43_wireless_core_exit(struct b43_wldev *dev); 365static void b43_wireless_core_exit(struct b43_wldev *dev);
339static int b43_wireless_core_init(struct b43_wldev *dev); 366static int b43_wireless_core_init(struct b43_wldev *dev);
340static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev); 367static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
@@ -2953,6 +2980,45 @@ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
2953 } 2980 }
2954} 2981}
2955 2982
2983/* brcms_b_switch_macfreq */
2984void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode)
2985{
2986 u16 chip_id = dev->dev->chip_id;
2987
2988 if (chip_id == BCMA_CHIP_ID_BCM43217 ||
2989 chip_id == BCMA_CHIP_ID_BCM43222 ||
2990 chip_id == BCMA_CHIP_ID_BCM43224 ||
2991 chip_id == BCMA_CHIP_ID_BCM43225 ||
2992 chip_id == BCMA_CHIP_ID_BCM43227 ||
2993 chip_id == BCMA_CHIP_ID_BCM43228) {
2994 switch (spurmode) {
2995 case 2: /* 126 Mhz */
2996 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
2997 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
2998 break;
2999 case 1: /* 123 Mhz */
3000 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
3001 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
3002 break;
3003 default: /* 120 Mhz */
3004 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
3005 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
3006 break;
3007 }
3008 } else if (dev->phy.type == B43_PHYTYPE_LCN) {
3009 switch (spurmode) {
3010 case 1: /* 82 Mhz */
3011 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
3012 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
3013 break;
3014 default: /* 80 Mhz */
3015 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
3016 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
3017 break;
3018 }
3019 }
3020}
3021
2956static void b43_adjust_opmode(struct b43_wldev *dev) 3022static void b43_adjust_opmode(struct b43_wldev *dev)
2957{ 3023{
2958 struct b43_wl *wl = dev->wl; 3024 struct b43_wl *wl = dev->wl;
@@ -4335,8 +4401,9 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4335 u8 phy_type; 4401 u8 phy_type;
4336 u8 phy_rev; 4402 u8 phy_rev;
4337 u16 radio_manuf; 4403 u16 radio_manuf;
4338 u16 radio_ver; 4404 u16 radio_id;
4339 u16 radio_rev; 4405 u16 radio_rev;
4406 u8 radio_ver;
4340 int unsupported = 0; 4407 int unsupported = 0;
4341 4408
4342 /* Get PHY versioning */ 4409 /* Get PHY versioning */
@@ -4360,7 +4427,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4360#endif 4427#endif
4361#ifdef CONFIG_B43_PHY_N 4428#ifdef CONFIG_B43_PHY_N
4362 case B43_PHYTYPE_N: 4429 case B43_PHYTYPE_N:
4363 if (phy_rev > 9) 4430 if (phy_rev >= 19)
4364 unsupported = 1; 4431 unsupported = 1;
4365 break; 4432 break;
4366#endif 4433#endif
@@ -4402,7 +4469,9 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4402 radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA); 4469 radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
4403 4470
4404 b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1); 4471 b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
4405 radio_ver = b43_read16(dev, B43_MMIO_RADIO24_DATA); 4472 radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
4473
4474 radio_ver = 0; /* Is there version somewhere? */
4406 } else if (core_rev >= 24) { 4475 } else if (core_rev >= 24) {
4407 u16 radio24[3]; 4476 u16 radio24[3];
4408 4477
@@ -4411,12 +4480,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4411 radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA); 4480 radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
4412 } 4481 }
4413 4482
4414 /* Broadcom uses "id" for our "ver" and has separated "ver" */
4415 /* radio_ver = (radio24[0] & 0xF0) >> 4; */
4416
4417 radio_manuf = 0x17F; 4483 radio_manuf = 0x17F;
4418 radio_ver = (radio24[2] << 8) | radio24[1]; 4484 radio_id = (radio24[2] << 8) | radio24[1];
4419 radio_rev = (radio24[0] & 0xF); 4485 radio_rev = (radio24[0] & 0xF);
4486 radio_ver = (radio24[0] & 0xF0) >> 4;
4420 } else { 4487 } else {
4421 if (dev->dev->chip_id == 0x4317) { 4488 if (dev->dev->chip_id == 0x4317) {
4422 if (dev->dev->chip_rev == 0) 4489 if (dev->dev->chip_rev == 0)
@@ -4435,15 +4502,16 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4435 << 16; 4502 << 16;
4436 } 4503 }
4437 radio_manuf = (tmp & 0x00000FFF); 4504 radio_manuf = (tmp & 0x00000FFF);
4438 radio_ver = (tmp & 0x0FFFF000) >> 12; 4505 radio_id = (tmp & 0x0FFFF000) >> 12;
4439 radio_rev = (tmp & 0xF0000000) >> 28; 4506 radio_rev = (tmp & 0xF0000000) >> 28;
4507 radio_ver = 0; /* Probably not available on old hw */
4440 } 4508 }
4441 4509
4442 if (radio_manuf != 0x17F /* Broadcom */) 4510 if (radio_manuf != 0x17F /* Broadcom */)
4443 unsupported = 1; 4511 unsupported = 1;
4444 switch (phy_type) { 4512 switch (phy_type) {
4445 case B43_PHYTYPE_A: 4513 case B43_PHYTYPE_A:
4446 if (radio_ver != 0x2060) 4514 if (radio_id != 0x2060)
4447 unsupported = 1; 4515 unsupported = 1;
4448 if (radio_rev != 1) 4516 if (radio_rev != 1)
4449 unsupported = 1; 4517 unsupported = 1;
@@ -4451,43 +4519,49 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4451 unsupported = 1; 4519 unsupported = 1;
4452 break; 4520 break;
4453 case B43_PHYTYPE_B: 4521 case B43_PHYTYPE_B:
4454 if ((radio_ver & 0xFFF0) != 0x2050) 4522 if ((radio_id & 0xFFF0) != 0x2050)
4455 unsupported = 1; 4523 unsupported = 1;
4456 break; 4524 break;
4457 case B43_PHYTYPE_G: 4525 case B43_PHYTYPE_G:
4458 if (radio_ver != 0x2050) 4526 if (radio_id != 0x2050)
4459 unsupported = 1; 4527 unsupported = 1;
4460 break; 4528 break;
4461 case B43_PHYTYPE_N: 4529 case B43_PHYTYPE_N:
4462 if (radio_ver != 0x2055 && radio_ver != 0x2056) 4530 if (radio_id != 0x2055 && radio_id != 0x2056 &&
4531 radio_id != 0x2057)
4532 unsupported = 1;
4533 if (radio_id == 0x2057 &&
4534 !(radio_rev == 9 || radio_rev == 14))
4463 unsupported = 1; 4535 unsupported = 1;
4464 break; 4536 break;
4465 case B43_PHYTYPE_LP: 4537 case B43_PHYTYPE_LP:
4466 if (radio_ver != 0x2062 && radio_ver != 0x2063) 4538 if (radio_id != 0x2062 && radio_id != 0x2063)
4467 unsupported = 1; 4539 unsupported = 1;
4468 break; 4540 break;
4469 case B43_PHYTYPE_HT: 4541 case B43_PHYTYPE_HT:
4470 if (radio_ver != 0x2059) 4542 if (radio_id != 0x2059)
4471 unsupported = 1; 4543 unsupported = 1;
4472 break; 4544 break;
4473 case B43_PHYTYPE_LCN: 4545 case B43_PHYTYPE_LCN:
4474 if (radio_ver != 0x2064) 4546 if (radio_id != 0x2064)
4475 unsupported = 1; 4547 unsupported = 1;
4476 break; 4548 break;
4477 default: 4549 default:
4478 B43_WARN_ON(1); 4550 B43_WARN_ON(1);
4479 } 4551 }
4480 if (unsupported) { 4552 if (unsupported) {
4481 b43err(dev->wl, "FOUND UNSUPPORTED RADIO " 4553 b43err(dev->wl,
4482 "(Manuf 0x%X, Version 0x%X, Revision %u)\n", 4554 "FOUND UNSUPPORTED RADIO (Manuf 0x%X, ID 0x%X, Revision %u, Version %u)\n",
4483 radio_manuf, radio_ver, radio_rev); 4555 radio_manuf, radio_id, radio_rev, radio_ver);
4484 return -EOPNOTSUPP; 4556 return -EOPNOTSUPP;
4485 } 4557 }
4486 b43dbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n", 4558 b43info(dev->wl,
4487 radio_manuf, radio_ver, radio_rev); 4559 "Found Radio: Manuf 0x%X, ID 0x%X, Revision %u, Version %u\n",
4560 radio_manuf, radio_id, radio_rev, radio_ver);
4488 4561
4562 /* FIXME: b43 treats "id" as "ver" and ignores the real "ver" */
4489 phy->radio_manuf = radio_manuf; 4563 phy->radio_manuf = radio_manuf;
4490 phy->radio_ver = radio_ver; 4564 phy->radio_ver = radio_id;
4491 phy->radio_rev = radio_rev; 4565 phy->radio_rev = radio_rev;
4492 4566
4493 phy->analog = analog_type; 4567 phy->analog = analog_type;
@@ -5095,12 +5169,24 @@ static int b43_setup_bands(struct b43_wldev *dev,
5095 bool have_2ghz_phy, bool have_5ghz_phy) 5169 bool have_2ghz_phy, bool have_5ghz_phy)
5096{ 5170{
5097 struct ieee80211_hw *hw = dev->wl->hw; 5171 struct ieee80211_hw *hw = dev->wl->hw;
5172 struct b43_phy *phy = &dev->phy;
5173 bool limited_2g;
5174 bool limited_5g;
5175
5176 /* We don't support all 2 GHz channels on some devices */
5177 limited_2g = phy->radio_ver == 0x2057 &&
5178 (phy->radio_rev == 9 || phy->radio_rev == 14);
5179 limited_5g = phy->radio_ver == 0x2057 &&
5180 phy->radio_rev == 9;
5098 5181
5099 if (have_2ghz_phy) 5182 if (have_2ghz_phy)
5100 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz; 5183 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = limited_2g ?
5184 &b43_band_2ghz_limited : &b43_band_2GHz;
5101 if (dev->phy.type == B43_PHYTYPE_N) { 5185 if (dev->phy.type == B43_PHYTYPE_N) {
5102 if (have_5ghz_phy) 5186 if (have_5ghz_phy)
5103 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy; 5187 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = limited_5g ?
5188 &b43_band_5GHz_nphy_limited :
5189 &b43_band_5GHz_nphy;
5104 } else { 5190 } else {
5105 if (have_5ghz_phy) 5191 if (have_5ghz_phy)
5106 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy; 5192 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy;
@@ -5248,14 +5334,15 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
5248 b43_supported_bands(dev, &have_2ghz_phy, &have_5ghz_phy); 5334 b43_supported_bands(dev, &have_2ghz_phy, &have_5ghz_phy);
5249 5335
5250 /* We don't support 5 GHz on some PHYs yet */ 5336 /* We don't support 5 GHz on some PHYs yet */
5251 switch (dev->phy.type) { 5337 if (have_5ghz_phy) {
5252 case B43_PHYTYPE_A: 5338 switch (dev->phy.type) {
5253 case B43_PHYTYPE_G: 5339 case B43_PHYTYPE_A:
5254 case B43_PHYTYPE_N: 5340 case B43_PHYTYPE_G:
5255 case B43_PHYTYPE_LP: 5341 case B43_PHYTYPE_LP:
5256 case B43_PHYTYPE_HT: 5342 case B43_PHYTYPE_HT:
5257 b43warn(wl, "5 GHz band is unsupported on this PHY\n"); 5343 b43warn(wl, "5 GHz band is unsupported on this PHY\n");
5258 have_5ghz_phy = false; 5344 have_5ghz_phy = false;
5345 }
5259 } 5346 }
5260 5347
5261 if (!have_2ghz_phy && !have_5ghz_phy) { 5348 if (!have_2ghz_phy && !have_5ghz_phy) {