diff options
author | David S. Miller <davem@davemloft.net> | 2010-02-14 20:45:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-14 20:45:59 -0500 |
commit | f6f223039c0d0683bdea1eabd35b309e10311a60 (patch) | |
tree | 890e07acf8c18ddc2994ebc0a0bdcdda38b0dcc6 /drivers/net/wireless/b43 | |
parent | b3b3f04fb587ecb61b5baa6c1c5f0e666fd12d73 (diff) | |
parent | 42c4568a4ace0adc27a9d6f02936e2047ba6fc7e (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.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/b43/dma.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/b43/dma.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_n.c | 302 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_n.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/b43/pio.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/b43/pio.h | 5 |
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 | ||
1503 | void 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 | |||
1519 | static void dma_rx(struct b43_dmaring *ring, int *slot) | 1502 | static 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); | |||
278 | void b43_dma_tx_suspend(struct b43_wldev *dev); | 276 | void b43_dma_tx_suspend(struct b43_wldev *dev); |
279 | void b43_dma_tx_resume(struct b43_wldev *dev); | 277 | void b43_dma_tx_resume(struct b43_wldev *dev); |
280 | 278 | ||
281 | void b43_dma_get_tx_stats(struct b43_wldev *dev, | ||
282 | struct ieee80211_tx_queue_stats *stats); | ||
283 | |||
284 | int b43_dma_tx(struct b43_wldev *dev, | 279 | int b43_dma_tx(struct b43_wldev *dev, |
285 | struct sk_buff *skb); | 280 | struct sk_buff *skb); |
286 | void b43_dma_handle_txstatus(struct b43_wldev *dev, | 281 | void 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) | |||
637 | static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) | 637 | static 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 | ||
646 | static void b43_short_slot_timing_enable(struct b43_wldev *dev) | 653 | static 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 | ||
3352 | static 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 | |||
3373 | static int b43_op_get_stats(struct ieee80211_hw *hw, | 3359 | static 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 | ||
4396 | out: | 4381 | out: |
@@ -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); |
69 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | 69 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, |
70 | enum b43_nphy_rf_sequence seq); | 70 | enum b43_nphy_rf_sequence seq); |
71 | static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | ||
72 | u16 value, u8 core, bool off); | ||
73 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | ||
74 | u16 value, u8 core); | ||
71 | 75 | ||
72 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) | 76 | void 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 */ | ||
721 | static 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 */ |
718 | static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) | 782 | static 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 */ | ||
1021 | static 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 */ |
957 | static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, | 1048 | static 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 */ | ||
1363 | static 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 | |||
1267 | static void b43_nphy_bphy_init(struct b43_wldev *dev) | 1460 | static 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 */ | ||
2391 | static 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 */ |
2198 | static void b43_nphy_restore_cal(struct b43_wldev *dev) | 2440 | static 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 */ | ||
2732 | static 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 */ |
2490 | static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | 2765 | static 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 | ||
608 | void 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. */ |
625 | static bool pio_rx_frame(struct b43_pio_rxqueue *q) | 608 | static 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); | |||
160 | int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb); | 157 | int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb); |
161 | void b43_pio_handle_txstatus(struct b43_wldev *dev, | 158 | void b43_pio_handle_txstatus(struct b43_wldev *dev, |
162 | const struct b43_txstatus *status); | 159 | const struct b43_txstatus *status); |
163 | void b43_pio_get_tx_stats(struct b43_wldev *dev, | ||
164 | struct ieee80211_tx_queue_stats *stats); | ||
165 | void b43_pio_rx(struct b43_pio_rxqueue *q); | 160 | void b43_pio_rx(struct b43_pio_rxqueue *q); |
166 | 161 | ||
167 | void b43_pio_tx_suspend(struct b43_wldev *dev); | 162 | void b43_pio_tx_suspend(struct b43_wldev *dev); |