aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-14 20:45:59 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-14 20:45:59 -0500
commitf6f223039c0d0683bdea1eabd35b309e10311a60 (patch)
tree890e07acf8c18ddc2994ebc0a0bdcdda38b0dcc6 /drivers/net/wireless/b43
parentb3b3f04fb587ecb61b5baa6c1c5f0e666fd12d73 (diff)
parent42c4568a4ace0adc27a9d6f02936e2047ba6fc7e (diff)
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/b43.h1
-rw-r--r--drivers/net/wireless/b43/dma.c17
-rw-r--r--drivers/net/wireless/b43/dma.h5
-rw-r--r--drivers/net/wireless/b43/main.c38
-rw-r--r--drivers/net/wireless/b43/phy_n.c302
-rw-r--r--drivers/net/wireless/b43/phy_n.h4
-rw-r--r--drivers/net/wireless/b43/pio.c17
-rw-r--r--drivers/net/wireless/b43/pio.h5
8 files changed, 305 insertions, 84 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 54d6085a887b..6a6ab0f630e5 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -115,6 +115,7 @@
115#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ 115#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */
116#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */ 116#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */
117#define B43_MMIO_RNG 0x65A 117#define B43_MMIO_RNG 0x65A
118#define B43_MMIO_IFSSLOT 0x684 /* Interframe slot time */
118#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */ 119#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
119#define B43_MMIO_IFSCTL_USE_EDCF 0x0004 120#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
120#define B43_MMIO_POWERUP_DELAY 0x6A8 121#define B43_MMIO_POWERUP_DELAY 0x6A8
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 615af22c49fd..be7abf8916ad 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1369,7 +1369,6 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1369 b43err(dev->wl, "DMA tx mapping failure\n"); 1369 b43err(dev->wl, "DMA tx mapping failure\n");
1370 goto out; 1370 goto out;
1371 } 1371 }
1372 ring->nr_tx_packets++;
1373 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || 1372 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
1374 should_inject_overflow(ring)) { 1373 should_inject_overflow(ring)) {
1375 /* This TX ring is full. */ 1374 /* This TX ring is full. */
@@ -1500,22 +1499,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1500 } 1499 }
1501} 1500}
1502 1501
1503void b43_dma_get_tx_stats(struct b43_wldev *dev,
1504 struct ieee80211_tx_queue_stats *stats)
1505{
1506 const int nr_queues = dev->wl->hw->queues;
1507 struct b43_dmaring *ring;
1508 int i;
1509
1510 for (i = 0; i < nr_queues; i++) {
1511 ring = select_ring_by_priority(dev, i);
1512
1513 stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME;
1514 stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME;
1515 stats[i].count = ring->nr_tx_packets;
1516 }
1517}
1518
1519static void dma_rx(struct b43_dmaring *ring, int *slot) 1502static void dma_rx(struct b43_dmaring *ring, int *slot)
1520{ 1503{
1521 const struct b43_dma_ops *ops = ring->ops; 1504 const struct b43_dma_ops *ops = ring->ops;
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index f7ab37c4cdbc..dc91944d6022 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -228,8 +228,6 @@ struct b43_dmaring {
228 int used_slots; 228 int used_slots;
229 /* Currently used slot in the ring. */ 229 /* Currently used slot in the ring. */
230 int current_slot; 230 int current_slot;
231 /* Total number of packets sent. Statistics only. */
232 unsigned int nr_tx_packets;
233 /* Frameoffset in octets. */ 231 /* Frameoffset in octets. */
234 u32 frameoffset; 232 u32 frameoffset;
235 /* Descriptor buffer size. */ 233 /* Descriptor buffer size. */
@@ -278,9 +276,6 @@ void b43_dma_free(struct b43_wldev *dev);
278void b43_dma_tx_suspend(struct b43_wldev *dev); 276void b43_dma_tx_suspend(struct b43_wldev *dev);
279void b43_dma_tx_resume(struct b43_wldev *dev); 277void b43_dma_tx_resume(struct b43_wldev *dev);
280 278
281void b43_dma_get_tx_stats(struct b43_wldev *dev,
282 struct ieee80211_tx_queue_stats *stats);
283
284int b43_dma_tx(struct b43_wldev *dev, 279int b43_dma_tx(struct b43_wldev *dev,
285 struct sk_buff *skb); 280 struct sk_buff *skb);
286void b43_dma_handle_txstatus(struct b43_wldev *dev, 281void b43_dma_handle_txstatus(struct b43_wldev *dev,
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 316a913860d7..aa33d741e5e6 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -637,10 +637,17 @@ static void b43_upload_card_macaddress(struct b43_wldev *dev)
637static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) 637static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time)
638{ 638{
639 /* slot_time is in usec. */ 639 /* slot_time is in usec. */
640 if (dev->phy.type != B43_PHYTYPE_G) 640 /* This test used to exit for all but a G PHY. */
641 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
641 return; 642 return;
642 b43_write16(dev, 0x684, 510 + slot_time); 643 b43_write16(dev, B43_MMIO_IFSSLOT, 510 + slot_time);
643 b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time); 644 /* Shared memory location 0x0010 is the slot time and should be
645 * set to slot_time; however, this register is initially 0 and changing
646 * the value adversely affects the transmit rate for BCM4311
647 * devices. Until this behavior is unterstood, delete this step
648 *
649 * b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);
650 */
644} 651}
645 652
646static void b43_short_slot_timing_enable(struct b43_wldev *dev) 653static void b43_short_slot_timing_enable(struct b43_wldev *dev)
@@ -3349,27 +3356,6 @@ out_unlock:
3349 return err; 3356 return err;
3350} 3357}
3351 3358
3352static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
3353 struct ieee80211_tx_queue_stats *stats)
3354{
3355 struct b43_wl *wl = hw_to_b43_wl(hw);
3356 struct b43_wldev *dev;
3357 int err = -ENODEV;
3358
3359 mutex_lock(&wl->mutex);
3360 dev = wl->current_dev;
3361 if (dev && b43_status(dev) >= B43_STAT_STARTED) {
3362 if (b43_using_pio_transfers(dev))
3363 b43_pio_get_tx_stats(dev, stats);
3364 else
3365 b43_dma_get_tx_stats(dev, stats);
3366 err = 0;
3367 }
3368 mutex_unlock(&wl->mutex);
3369
3370 return err;
3371}
3372
3373static int b43_op_get_stats(struct ieee80211_hw *hw, 3359static int b43_op_get_stats(struct ieee80211_hw *hw,
3374 struct ieee80211_low_level_stats *stats) 3360 struct ieee80211_low_level_stats *stats)
3375{ 3361{
@@ -3980,6 +3966,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3980 } 3966 }
3981 3967
3982 /* We are ready to run. */ 3968 /* We are ready to run. */
3969 ieee80211_wake_queues(dev->wl->hw);
3983 b43_set_status(dev, B43_STAT_STARTED); 3970 b43_set_status(dev, B43_STAT_STARTED);
3984 3971
3985 /* Start data flow (TX/RX). */ 3972 /* Start data flow (TX/RX). */
@@ -4389,8 +4376,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4389 4376
4390 ieee80211_wake_queues(dev->wl->hw); 4377 ieee80211_wake_queues(dev->wl->hw);
4391 4378
4392 ieee80211_wake_queues(dev->wl->hw);
4393
4394 b43_set_status(dev, B43_STAT_INITIALIZED); 4379 b43_set_status(dev, B43_STAT_INITIALIZED);
4395 4380
4396out: 4381out:
@@ -4596,7 +4581,6 @@ static const struct ieee80211_ops b43_hw_ops = {
4596 .set_key = b43_op_set_key, 4581 .set_key = b43_op_set_key,
4597 .update_tkip_key = b43_op_update_tkip_key, 4582 .update_tkip_key = b43_op_update_tkip_key,
4598 .get_stats = b43_op_get_stats, 4583 .get_stats = b43_op_get_stats,
4599 .get_tx_stats = b43_op_get_tx_stats,
4600 .get_tsf = b43_op_get_tsf, 4584 .get_tsf = b43_op_get_tsf,
4601 .set_tsf = b43_op_set_tsf, 4585 .set_tsf = b43_op_set_tsf,
4602 .start = b43_op_start, 4586 .start = b43_op_start,
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 6392da25efed..795bb1e3345d 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -68,6 +68,10 @@ static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
68 u8 *events, u8 *delays, u8 length); 68 u8 *events, u8 *delays, u8 length);
69static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, 69static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
70 enum b43_nphy_rf_sequence seq); 70 enum b43_nphy_rf_sequence seq);
71static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
72 u16 value, u8 core, bool off);
73static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
74 u16 value, u8 core);
71 75
72void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 76void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
73{//TODO 77{//TODO
@@ -498,8 +502,8 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
498 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007); 502 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007);
499 } 503 }
500 504
501 /* TODO: Call N PHY RF Ctrl Intc Override with 2, 0, 3 as arguments */ 505 b43_nphy_rf_control_intc_override(dev, 2, 0, 3);
502 /* TODO: Call N PHY RF Intc Override with 8, 0, 3, 0 as arguments */ 506 b43_nphy_rf_control_override(dev, 8, 0, 3, false);
503 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); 507 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
504 508
505 if (core == 0) { 509 if (core == 0) {
@@ -509,9 +513,8 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
509 rxval = 4; 513 rxval = 4;
510 txval = 2; 514 txval = 2;
511 } 515 }
512 516 b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1));
513 /* TODO: Call N PHY RF Ctrl Intc Override with 1, rxval, (core + 1) */ 517 b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core));
514 /* TODO: Call N PHY RF Ctrl Intc Override with 1, txval, (2 - core) */
515} 518}
516 519
517/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ 520/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
@@ -714,6 +717,67 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev)
714 b43_nphy_stay_in_carrier_search(dev, 0); 717 b43_nphy_stay_in_carrier_search(dev, 0);
715} 718}
716 719
720/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */
721static void b43_nphy_spur_workaround(struct b43_wldev *dev)
722{
723 struct b43_phy_n *nphy = dev->phy.n;
724
725 unsigned int channel;
726 int tone[2] = { 57, 58 };
727 u32 noise[2] = { 0x3FF, 0x3FF };
728
729 B43_WARN_ON(dev->phy.rev < 3);
730
731 if (nphy->hang_avoid)
732 b43_nphy_stay_in_carrier_search(dev, 1);
733
734 /* FIXME: channel = radio_chanspec */
735
736 if (nphy->gband_spurwar_en) {
737 /* TODO: N PHY Adjust Analog Pfbw (7) */
738 if (channel == 11 && dev->phy.is_40mhz)
739 ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
740 else
741 ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
742 /* TODO: N PHY Adjust CRS Min Power (0x1E) */
743 }
744
745 if (nphy->aband_spurwar_en) {
746 if (channel == 54) {
747 tone[0] = 0x20;
748 noise[0] = 0x25F;
749 } else if (channel == 38 || channel == 102 || channel == 118) {
750 if (0 /* FIXME */) {
751 tone[0] = 0x20;
752 noise[0] = 0x21F;
753 } else {
754 tone[0] = 0;
755 noise[0] = 0;
756 }
757 } else if (channel == 134) {
758 tone[0] = 0x20;
759 noise[0] = 0x21F;
760 } else if (channel == 151) {
761 tone[0] = 0x10;
762 noise[0] = 0x23F;
763 } else if (channel == 153 || channel == 161) {
764 tone[0] = 0x30;
765 noise[0] = 0x23F;
766 } else {
767 tone[0] = 0;
768 noise[0] = 0;
769 }
770
771 if (!tone[0] && !noise[0])
772 ; /* TODO: N PHY Adjust Min Noise Var(1, tone, noise)*/
773 else
774 ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
775 }
776
777 if (nphy->hang_avoid)
778 b43_nphy_stay_in_carrier_search(dev, 0);
779}
780
717/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ 781/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
718static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) 782static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
719{ 783{
@@ -953,6 +1017,33 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
953 b43_nphy_stay_in_carrier_search(dev, 0); 1017 b43_nphy_stay_in_carrier_search(dev, 0);
954} 1018}
955 1019
1020/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */
1021static int b43_nphy_load_samples(struct b43_wldev *dev,
1022 struct b43_c32 *samples, u16 len) {
1023 struct b43_phy_n *nphy = dev->phy.n;
1024 u16 i;
1025 u32 *data;
1026
1027 data = kzalloc(len * sizeof(u32), GFP_KERNEL);
1028 if (!data) {
1029 b43err(dev->wl, "allocation for samples loading failed\n");
1030 return -ENOMEM;
1031 }
1032 if (nphy->hang_avoid)
1033 b43_nphy_stay_in_carrier_search(dev, 1);
1034
1035 for (i = 0; i < len; i++) {
1036 data[i] = (samples[i].i & 0x3FF << 10);
1037 data[i] |= samples[i].q & 0x3FF;
1038 }
1039 b43_ntab_write_bulk(dev, B43_NTAB32(17, 0), len, data);
1040
1041 kfree(data);
1042 if (nphy->hang_avoid)
1043 b43_nphy_stay_in_carrier_search(dev, 0);
1044 return 0;
1045}
1046
956/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */ 1047/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */
957static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, 1048static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
958 bool test) 1049 bool test)
@@ -978,6 +1069,10 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
978 } 1069 }
979 1070
980 samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL); 1071 samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL);
1072 if (!samples) {
1073 b43err(dev->wl, "allocation for samples generation failed\n");
1074 return 0;
1075 }
981 rot = (((freq * 36) / bw) << 16) / 100; 1076 rot = (((freq * 36) / bw) << 16) / 100;
982 angle = 0; 1077 angle = 0;
983 1078
@@ -988,9 +1083,9 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
988 samples[i].i = CORDIC_CONVERT(samples[i].i * max); 1083 samples[i].i = CORDIC_CONVERT(samples[i].i * max);
989 } 1084 }
990 1085
991 /* TODO: Call N PHY Load Sample Table with buffer, len as arguments */ 1086 i = b43_nphy_load_samples(dev, samples, len);
992 kfree(samples); 1087 kfree(samples);
993 return len; 1088 return (i < 0) ? 0 : len;
994} 1089}
995 1090
996/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ 1091/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
@@ -1264,6 +1359,104 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
1264 } 1359 }
1265} 1360}
1266 1361
1362/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */
1363static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
1364 u16 value, u8 core)
1365{
1366 u8 i, j;
1367 u16 reg, tmp, val;
1368
1369 B43_WARN_ON(dev->phy.rev < 3);
1370 B43_WARN_ON(field > 4);
1371
1372 for (i = 0; i < 2; i++) {
1373 if ((core == 1 && i == 1) || (core == 2 && !i))
1374 continue;
1375
1376 reg = (i == 0) ?
1377 B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
1378 b43_phy_mask(dev, reg, 0xFBFF);
1379
1380 switch (field) {
1381 case 0:
1382 b43_phy_write(dev, reg, 0);
1383 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1384 break;
1385 case 1:
1386 if (!i) {
1387 b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1,
1388 0xFC3F, (value << 6));
1389 b43_phy_maskset(dev, B43_NPHY_TXF_40CO_B1S1,
1390 0xFFFE, 1);
1391 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1392 B43_NPHY_RFCTL_CMD_START);
1393 for (j = 0; j < 100; j++) {
1394 if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) {
1395 j = 0;
1396 break;
1397 }
1398 udelay(10);
1399 }
1400 if (j)
1401 b43err(dev->wl,
1402 "intc override timeout\n");
1403 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1,
1404 0xFFFE);
1405 } else {
1406 b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC2,
1407 0xFC3F, (value << 6));
1408 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
1409 0xFFFE, 1);
1410 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1411 B43_NPHY_RFCTL_CMD_RXTX);
1412 for (j = 0; j < 100; j++) {
1413 if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) {
1414 j = 0;
1415 break;
1416 }
1417 udelay(10);
1418 }
1419 if (j)
1420 b43err(dev->wl,
1421 "intc override timeout\n");
1422 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
1423 0xFFFE);
1424 }
1425 break;
1426 case 2:
1427 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1428 tmp = 0x0020;
1429 val = value << 5;
1430 } else {
1431 tmp = 0x0010;
1432 val = value << 4;
1433 }
1434 b43_phy_maskset(dev, reg, ~tmp, val);
1435 break;
1436 case 3:
1437 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1438 tmp = 0x0001;
1439 val = value;
1440 } else {
1441 tmp = 0x0004;
1442 val = value << 2;
1443 }
1444 b43_phy_maskset(dev, reg, ~tmp, val);
1445 break;
1446 case 4:
1447 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1448 tmp = 0x0002;
1449 val = value << 1;
1450 } else {
1451 tmp = 0x0008;
1452 val = value << 3;
1453 }
1454 b43_phy_maskset(dev, reg, ~tmp, val);
1455 break;
1456 }
1457 }
1458}
1459
1267static void b43_nphy_bphy_init(struct b43_wldev *dev) 1460static void b43_nphy_bphy_init(struct b43_wldev *dev)
1268{ 1461{
1269 unsigned int i; 1462 unsigned int i;
@@ -2161,9 +2354,9 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2161 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); 2354 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2162 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); 2355 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2163 2356
2164 /* TODO: Call N PHY RF Ctrl Intc Override with 2, 1, 3 */ 2357 b43_nphy_rf_control_intc_override(dev, 2, 1, 3);
2165 /* TODO: Call N PHY RF Ctrl Intc Override with 1, 2, 1 */ 2358 b43_nphy_rf_control_intc_override(dev, 1, 2, 1);
2166 /* TODO: Call N PHY RF Ctrl Intc Override with 1, 8, 2 */ 2359 b43_nphy_rf_control_intc_override(dev, 1, 8, 2);
2167 2360
2168 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); 2361 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
2169 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); 2362 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
@@ -2194,6 +2387,55 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2194 } 2387 }
2195} 2388}
2196 2389
2390/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
2391static void b43_nphy_save_cal(struct b43_wldev *dev)
2392{
2393 struct b43_phy_n *nphy = dev->phy.n;
2394
2395 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2396 u16 *txcal_radio_regs = NULL;
2397 u8 *iqcal_chanspec;
2398 u16 *table = NULL;
2399
2400 if (nphy->hang_avoid)
2401 b43_nphy_stay_in_carrier_search(dev, 1);
2402
2403 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2404 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G;
2405 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G;
2406 iqcal_chanspec = &nphy->iqcal_chanspec_2G;
2407 table = nphy->cal_cache.txcal_coeffs_2G;
2408 } else {
2409 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G;
2410 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G;
2411 iqcal_chanspec = &nphy->iqcal_chanspec_5G;
2412 table = nphy->cal_cache.txcal_coeffs_5G;
2413 }
2414
2415 b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
2416 /* TODO use some definitions */
2417 if (dev->phy.rev >= 3) {
2418 txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
2419 txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
2420 txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
2421 txcal_radio_regs[3] = b43_radio_read(dev, 0x3022);
2422 txcal_radio_regs[4] = b43_radio_read(dev, 0x2023);
2423 txcal_radio_regs[5] = b43_radio_read(dev, 0x2024);
2424 txcal_radio_regs[6] = b43_radio_read(dev, 0x3023);
2425 txcal_radio_regs[7] = b43_radio_read(dev, 0x3024);
2426 } else {
2427 txcal_radio_regs[0] = b43_radio_read(dev, 0x8B);
2428 txcal_radio_regs[1] = b43_radio_read(dev, 0xBA);
2429 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
2430 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
2431 }
2432 *iqcal_chanspec = nphy->radio_chanspec;
2433 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table);
2434
2435 if (nphy->hang_avoid)
2436 b43_nphy_stay_in_carrier_search(dev, 0);
2437}
2438
2197/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */ 2439/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
2198static void b43_nphy_restore_cal(struct b43_wldev *dev) 2440static void b43_nphy_restore_cal(struct b43_wldev *dev)
2199{ 2441{
@@ -2486,6 +2728,39 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2486 return error; 2728 return error;
2487} 2729}
2488 2730
2731/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ReapplyTxCalCoeffs */
2732static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
2733{
2734 struct b43_phy_n *nphy = dev->phy.n;
2735 u8 i;
2736 u16 buffer[7];
2737 bool equal = true;
2738
2739 if (!nphy->txiqlocal_coeffsvalid || 1 /* FIXME */)
2740 return;
2741
2742 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
2743 for (i = 0; i < 4; i++) {
2744 if (buffer[i] != nphy->txiqlocal_bestc[i]) {
2745 equal = false;
2746 break;
2747 }
2748 }
2749
2750 if (!equal) {
2751 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4,
2752 nphy->txiqlocal_bestc);
2753 for (i = 0; i < 4; i++)
2754 buffer[i] = 0;
2755 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
2756 buffer);
2757 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
2758 &nphy->txiqlocal_bestc[5]);
2759 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
2760 &nphy->txiqlocal_bestc[5]);
2761 }
2762}
2763
2489/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */ 2764/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */
2490static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, 2765static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
2491 struct nphy_txgains target, u8 type, bool debug) 2766 struct nphy_txgains target, u8 type, bool debug)
@@ -2516,7 +2791,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
2516 b43_nphy_stay_in_carrier_search(dev, 1); 2791 b43_nphy_stay_in_carrier_search(dev, 1);
2517 2792
2518 if (dev->phy.rev < 2) 2793 if (dev->phy.rev < 2)
2519 ;/* TODO: Call N PHY Reapply TX Cal Coeffs */ 2794 b43_nphy_reapply_tx_cal_coeffs(dev);
2520 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); 2795 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
2521 for (i = 0; i < 2; i++) { 2796 for (i = 0; i < 2; i++) {
2522 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]); 2797 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]);
@@ -2858,7 +3133,7 @@ int b43_phy_initn(struct b43_wldev *dev)
2858 3133
2859 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) { 3134 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
2860 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0) 3135 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
2861 ;/* Call N PHY Save Cal */ 3136 b43_nphy_save_cal(dev);
2862 else if (nphy->mphase_cal_phase_id == 0) 3137 else if (nphy->mphase_cal_phase_id == 0)
2863 ;/* N PHY Periodic Calibration with argument 3 */ 3138 ;/* N PHY Periodic Calibration with argument 3 */
2864 } else { 3139 } else {
@@ -2872,7 +3147,8 @@ int b43_phy_initn(struct b43_wldev *dev)
2872 if (phy->rev >= 3 && phy->rev <= 6) 3147 if (phy->rev >= 3 && phy->rev <= 6)
2873 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014); 3148 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014);
2874 b43_nphy_tx_lp_fbw(dev); 3149 b43_nphy_tx_lp_fbw(dev);
2875 /* TODO N PHY Spur Workaround */ 3150 if (phy->rev >= 3)
3151 b43_nphy_spur_workaround(dev);
2876 3152
2877 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); 3153 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
2878 return 0; 3154 return 0;
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index ae82f0fc2096..403aad3f894f 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -975,6 +975,7 @@ struct b43_phy_n {
975 u16 papd_epsilon_offset[2]; 975 u16 papd_epsilon_offset[2];
976 s32 preamble_override; 976 s32 preamble_override;
977 u32 bb_mult_save; 977 u32 bb_mult_save;
978 u16 radio_chanspec;
978 979
979 bool gain_boost; 980 bool gain_boost;
980 bool elna_gain_config; 981 bool elna_gain_config;
@@ -1001,6 +1002,9 @@ struct b43_phy_n {
1001 u16 classifier_state; 1002 u16 classifier_state;
1002 u16 clip_state[2]; 1003 u16 clip_state[2];
1003 1004
1005 bool aband_spurwar_en;
1006 bool gband_spurwar_en;
1007
1004 bool ipa2g_on; 1008 bool ipa2g_on;
1005 u8 iqcal_chanspec_2G; 1009 u8 iqcal_chanspec_2G;
1006 u8 rssical_chanspec_2G; 1010 u8 rssical_chanspec_2G;
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index c01b8e02412f..a6062c3e89a5 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -559,7 +559,6 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
559 b43err(dev->wl, "PIO transmission failure\n"); 559 b43err(dev->wl, "PIO transmission failure\n");
560 goto out; 560 goto out;
561 } 561 }
562 q->nr_tx_packets++;
563 562
564 B43_WARN_ON(q->buffer_used > q->buffer_size); 563 B43_WARN_ON(q->buffer_used > q->buffer_size);
565 if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || 564 if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
@@ -605,22 +604,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
605 } 604 }
606} 605}
607 606
608void b43_pio_get_tx_stats(struct b43_wldev *dev,
609 struct ieee80211_tx_queue_stats *stats)
610{
611 const int nr_queues = dev->wl->hw->queues;
612 struct b43_pio_txqueue *q;
613 int i;
614
615 for (i = 0; i < nr_queues; i++) {
616 q = select_queue_by_priority(dev, i);
617
618 stats[i].len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots;
619 stats[i].limit = B43_PIO_MAX_NR_TXPACKETS;
620 stats[i].count = q->nr_tx_packets;
621 }
622}
623
624/* Returns whether we should fetch another frame. */ 607/* Returns whether we should fetch another frame. */
625static bool pio_rx_frame(struct b43_pio_rxqueue *q) 608static bool pio_rx_frame(struct b43_pio_rxqueue *q)
626{ 609{
diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h
index 7b3c42f93a16..1e516147424f 100644
--- a/drivers/net/wireless/b43/pio.h
+++ b/drivers/net/wireless/b43/pio.h
@@ -90,9 +90,6 @@ struct b43_pio_txqueue {
90 struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS]; 90 struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS];
91 struct list_head packets_list; 91 struct list_head packets_list;
92 92
93 /* Total number of transmitted packets. */
94 unsigned int nr_tx_packets;
95
96 /* Shortcut to the 802.11 core revision. This is to 93 /* Shortcut to the 802.11 core revision. This is to
97 * avoid horrible pointer dereferencing in the fastpaths. */ 94 * avoid horrible pointer dereferencing in the fastpaths. */
98 u8 rev; 95 u8 rev;
@@ -160,8 +157,6 @@ void b43_pio_free(struct b43_wldev *dev);
160int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb); 157int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb);
161void b43_pio_handle_txstatus(struct b43_wldev *dev, 158void b43_pio_handle_txstatus(struct b43_wldev *dev,
162 const struct b43_txstatus *status); 159 const struct b43_txstatus *status);
163void b43_pio_get_tx_stats(struct b43_wldev *dev,
164 struct ieee80211_tx_queue_stats *stats);
165void b43_pio_rx(struct b43_pio_rxqueue *q); 160void b43_pio_rx(struct b43_pio_rxqueue *q);
166 161
167void b43_pio_tx_suspend(struct b43_wldev *dev); 162void b43_pio_tx_suspend(struct b43_wldev *dev);