diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/b43 | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/b43')
25 files changed, 4660 insertions, 649 deletions
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 54ea61c15d8b..0a00d42642cd 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config B43 | 1 | config B43 |
2 | tristate "Broadcom 43xx wireless support (mac80211 stack)" | 2 | tristate "Broadcom 43xx wireless support (mac80211 stack)" |
3 | depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA | 3 | depends on SSB_POSSIBLE && MAC80211 && HAS_DMA |
4 | select SSB | 4 | select SSB |
5 | select FW_LOADER | 5 | select FW_LOADER |
6 | ---help--- | 6 | ---help--- |
@@ -78,11 +78,11 @@ config B43_SDIO | |||
78 | 78 | ||
79 | If unsure, say N. | 79 | If unsure, say N. |
80 | 80 | ||
81 | # Data transfers to the device via PIO | 81 | #Data transfers to the device via PIO. We want it as a fallback even |
82 | # This is only needed on PCMCIA and SDIO devices. All others can do DMA properly. | 82 | # if we can do DMA. |
83 | config B43_PIO | 83 | config B43_PIO |
84 | bool | 84 | bool |
85 | depends on B43 && (B43_SDIO || B43_PCMCIA || B43_FORCE_PIO) | 85 | depends on B43 |
86 | select SSB_BLOCKIO | 86 | select SSB_BLOCKIO |
87 | default y | 87 | default y |
88 | 88 | ||
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 84772a2542dc..5e83b6f0a3a0 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile | |||
@@ -12,7 +12,7 @@ b43-y += xmit.o | |||
12 | b43-y += lo.o | 12 | b43-y += lo.o |
13 | b43-y += wa.o | 13 | b43-y += wa.o |
14 | b43-y += dma.o | 14 | b43-y += dma.o |
15 | b43-$(CONFIG_B43_PIO) += pio.o | 15 | b43-y += pio.o |
16 | b43-y += rfkill.o | 16 | b43-y += rfkill.o |
17 | b43-$(CONFIG_B43_LEDS) += leds.o | 17 | b43-$(CONFIG_B43_LEDS) += leds.o |
18 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o | 18 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 660716214d49..b8807fb12c92 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -26,8 +26,6 @@ | |||
26 | # define B43_DEBUG 0 | 26 | # define B43_DEBUG 0 |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | #define B43_RX_MAX_SSI 60 | ||
30 | |||
31 | /* MMIO offsets */ | 29 | /* MMIO offsets */ |
32 | #define B43_MMIO_DMA0_REASON 0x20 | 30 | #define B43_MMIO_DMA0_REASON 0x20 |
33 | #define B43_MMIO_DMA0_IRQ_MASK 0x24 | 31 | #define B43_MMIO_DMA0_IRQ_MASK 0x24 |
@@ -117,6 +115,7 @@ | |||
117 | #define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ | 115 | #define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ |
118 | #define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */ | 116 | #define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */ |
119 | #define B43_MMIO_RNG 0x65A | 117 | #define B43_MMIO_RNG 0x65A |
118 | #define B43_MMIO_IFSSLOT 0x684 /* Interframe slot time */ | ||
120 | #define B43_MMIO_IFSCTL 0x688 /* Interframe space control */ | 119 | #define B43_MMIO_IFSCTL 0x688 /* Interframe space control */ |
121 | #define B43_MMIO_IFSCTL_USE_EDCF 0x0004 | 120 | #define B43_MMIO_IFSCTL_USE_EDCF 0x0004 |
122 | #define B43_MMIO_POWERUP_DELAY 0x6A8 | 121 | #define B43_MMIO_POWERUP_DELAY 0x6A8 |
@@ -255,6 +254,14 @@ enum { | |||
255 | #define B43_SHM_SH_MAXBFRAMES 0x0080 /* Maximum number of frames in a burst */ | 254 | #define B43_SHM_SH_MAXBFRAMES 0x0080 /* Maximum number of frames in a burst */ |
256 | #define B43_SHM_SH_SPUWKUP 0x0094 /* pre-wakeup for synth PU in us */ | 255 | #define B43_SHM_SH_SPUWKUP 0x0094 /* pre-wakeup for synth PU in us */ |
257 | #define B43_SHM_SH_PRETBTT 0x0096 /* pre-TBTT in us */ | 256 | #define B43_SHM_SH_PRETBTT 0x0096 /* pre-TBTT in us */ |
257 | /* SHM_SHARED tx iq workarounds */ | ||
258 | #define B43_SHM_SH_NPHY_TXIQW0 0x0700 | ||
259 | #define B43_SHM_SH_NPHY_TXIQW1 0x0702 | ||
260 | #define B43_SHM_SH_NPHY_TXIQW2 0x0704 | ||
261 | #define B43_SHM_SH_NPHY_TXIQW3 0x0706 | ||
262 | /* SHM_SHARED tx pwr ctrl */ | ||
263 | #define B43_SHM_SH_NPHY_TXPWR_INDX0 0x0708 | ||
264 | #define B43_SHM_SH_NPHY_TXPWR_INDX1 0x070E | ||
258 | 265 | ||
259 | /* SHM_SCRATCH offsets */ | 266 | /* SHM_SCRATCH offsets */ |
260 | #define B43_SHM_SC_MINCONT 0x0003 /* Minimum contention window */ | 267 | #define B43_SHM_SC_MINCONT 0x0003 /* Minimum contention window */ |
@@ -695,6 +702,7 @@ struct b43_wldev { | |||
695 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ | 702 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ |
696 | bool qos_enabled; /* TRUE, if QoS is used. */ | 703 | bool qos_enabled; /* TRUE, if QoS is used. */ |
697 | bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ | 704 | bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ |
705 | bool use_pio; /* TRUE if next init should use PIO */ | ||
698 | 706 | ||
699 | /* PHY/Radio device. */ | 707 | /* PHY/Radio device. */ |
700 | struct b43_phy phy; | 708 | struct b43_phy phy; |
@@ -749,12 +757,6 @@ struct b43_wldev { | |||
749 | #endif | 757 | #endif |
750 | }; | 758 | }; |
751 | 759 | ||
752 | /* | ||
753 | * Include goes here to avoid a dependency problem. | ||
754 | * A better fix would be to integrate xmit.h into b43.h. | ||
755 | */ | ||
756 | #include "xmit.h" | ||
757 | |||
758 | /* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */ | 760 | /* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */ |
759 | struct b43_wl { | 761 | struct b43_wl { |
760 | /* Pointer to the active wireless device on this chip */ | 762 | /* Pointer to the active wireless device on this chip */ |
@@ -829,15 +831,9 @@ struct b43_wl { | |||
829 | /* The device LEDs. */ | 831 | /* The device LEDs. */ |
830 | struct b43_leds leds; | 832 | struct b43_leds leds; |
831 | 833 | ||
832 | #ifdef CONFIG_B43_PIO | 834 | /* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */ |
833 | /* | 835 | u8 pio_scratchspace[110] __attribute__((__aligned__(8))); |
834 | * RX/TX header/tail buffers used by the frame transmit functions. | 836 | u8 pio_tailspace[4] __attribute__((__aligned__(8))); |
835 | */ | ||
836 | struct b43_rxhdr_fw4 rxhdr; | ||
837 | struct b43_txhdr txhdr; | ||
838 | u8 rx_tail[4]; | ||
839 | u8 tx_tail[4]; | ||
840 | #endif /* CONFIG_B43_PIO */ | ||
841 | }; | 837 | }; |
842 | 838 | ||
843 | static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw) | 839 | static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw) |
@@ -888,20 +884,15 @@ static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) | |||
888 | 884 | ||
889 | static inline bool b43_using_pio_transfers(struct b43_wldev *dev) | 885 | static inline bool b43_using_pio_transfers(struct b43_wldev *dev) |
890 | { | 886 | { |
891 | #ifdef CONFIG_B43_PIO | ||
892 | return dev->__using_pio_transfers; | 887 | return dev->__using_pio_transfers; |
893 | #else | ||
894 | return 0; | ||
895 | #endif | ||
896 | } | 888 | } |
897 | 889 | ||
898 | #ifdef CONFIG_B43_FORCE_PIO | 890 | #ifdef CONFIG_B43_FORCE_PIO |
899 | # define B43_FORCE_PIO 1 | 891 | # define B43_PIO_DEFAULT 1 |
900 | #else | 892 | #else |
901 | # define B43_FORCE_PIO 0 | 893 | # define B43_PIO_DEFAULT 0 |
902 | #endif | 894 | #endif |
903 | 895 | ||
904 | |||
905 | /* Message printing */ | 896 | /* Message printing */ |
906 | void b43info(struct b43_wl *wl, const char *fmt, ...) | 897 | void b43info(struct b43_wl *wl, const char *fmt, ...) |
907 | __attribute__ ((format(printf, 2, 3))); | 898 | __attribute__ ((format(printf, 2, 3))); |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index de4e804bedf0..fa40fdfea719 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
40 | #include <linux/etherdevice.h> | 40 | #include <linux/etherdevice.h> |
41 | #include <linux/slab.h> | ||
41 | #include <asm/div64.h> | 42 | #include <asm/div64.h> |
42 | 43 | ||
43 | 44 | ||
@@ -770,7 +771,7 @@ static void free_all_descbuffers(struct b43_dmaring *ring) | |||
770 | for (i = 0; i < ring->nr_slots; i++) { | 771 | for (i = 0; i < ring->nr_slots; i++) { |
771 | desc = ring->ops->idx2desc(ring, i, &meta); | 772 | desc = ring->ops->idx2desc(ring, i, &meta); |
772 | 773 | ||
773 | if (!meta->skb) { | 774 | if (!meta->skb || b43_dma_ptr_is_poisoned(meta->skb)) { |
774 | B43_WARN_ON(!ring->tx); | 775 | B43_WARN_ON(!ring->tx); |
775 | continue; | 776 | continue; |
776 | } | 777 | } |
@@ -822,7 +823,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
822 | enum b43_dmatype type) | 823 | enum b43_dmatype type) |
823 | { | 824 | { |
824 | struct b43_dmaring *ring; | 825 | struct b43_dmaring *ring; |
825 | int err; | 826 | int i, err; |
826 | dma_addr_t dma_test; | 827 | dma_addr_t dma_test; |
827 | 828 | ||
828 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); | 829 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); |
@@ -837,6 +838,8 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
837 | GFP_KERNEL); | 838 | GFP_KERNEL); |
838 | if (!ring->meta) | 839 | if (!ring->meta) |
839 | goto err_kfree_ring; | 840 | goto err_kfree_ring; |
841 | for (i = 0; i < ring->nr_slots; i++) | ||
842 | ring->meta->skb = B43_DMA_PTR_POISON; | ||
840 | 843 | ||
841 | ring->type = type; | 844 | ring->type = type; |
842 | ring->dev = dev; | 845 | ring->dev = dev; |
@@ -1147,28 +1150,29 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot) | |||
1147 | case 0x5000: | 1150 | case 0x5000: |
1148 | ring = dma->tx_ring_mcast; | 1151 | ring = dma->tx_ring_mcast; |
1149 | break; | 1152 | break; |
1150 | default: | ||
1151 | B43_WARN_ON(1); | ||
1152 | } | 1153 | } |
1153 | *slot = (cookie & 0x0FFF); | 1154 | *slot = (cookie & 0x0FFF); |
1154 | B43_WARN_ON(!(ring && *slot >= 0 && *slot < ring->nr_slots)); | 1155 | if (unlikely(!ring || *slot < 0 || *slot >= ring->nr_slots)) { |
1156 | b43dbg(dev->wl, "TX-status contains " | ||
1157 | "invalid cookie: 0x%04X\n", cookie); | ||
1158 | return NULL; | ||
1159 | } | ||
1155 | 1160 | ||
1156 | return ring; | 1161 | return ring; |
1157 | } | 1162 | } |
1158 | 1163 | ||
1159 | static int dma_tx_fragment(struct b43_dmaring *ring, | 1164 | static int dma_tx_fragment(struct b43_dmaring *ring, |
1160 | struct sk_buff **in_skb) | 1165 | struct sk_buff *skb) |
1161 | { | 1166 | { |
1162 | struct sk_buff *skb = *in_skb; | ||
1163 | const struct b43_dma_ops *ops = ring->ops; | 1167 | const struct b43_dma_ops *ops = ring->ops; |
1164 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1168 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1169 | struct b43_private_tx_info *priv_info = b43_get_priv_tx_info(info); | ||
1165 | u8 *header; | 1170 | u8 *header; |
1166 | int slot, old_top_slot, old_used_slots; | 1171 | int slot, old_top_slot, old_used_slots; |
1167 | int err; | 1172 | int err; |
1168 | struct b43_dmadesc_generic *desc; | 1173 | struct b43_dmadesc_generic *desc; |
1169 | struct b43_dmadesc_meta *meta; | 1174 | struct b43_dmadesc_meta *meta; |
1170 | struct b43_dmadesc_meta *meta_hdr; | 1175 | struct b43_dmadesc_meta *meta_hdr; |
1171 | struct sk_buff *bounce_skb; | ||
1172 | u16 cookie; | 1176 | u16 cookie; |
1173 | size_t hdrsize = b43_txhdr_size(ring->dev); | 1177 | size_t hdrsize = b43_txhdr_size(ring->dev); |
1174 | 1178 | ||
@@ -1212,34 +1216,28 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1212 | 1216 | ||
1213 | meta->skb = skb; | 1217 | meta->skb = skb; |
1214 | meta->is_last_fragment = 1; | 1218 | meta->is_last_fragment = 1; |
1219 | priv_info->bouncebuffer = NULL; | ||
1215 | 1220 | ||
1216 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1221 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
1217 | /* create a bounce buffer in zone_dma on mapping failure. */ | 1222 | /* create a bounce buffer in zone_dma on mapping failure. */ |
1218 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { | 1223 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
1219 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); | 1224 | priv_info->bouncebuffer = kmalloc(skb->len, GFP_ATOMIC | GFP_DMA); |
1220 | if (!bounce_skb) { | 1225 | if (!priv_info->bouncebuffer) { |
1221 | ring->current_slot = old_top_slot; | 1226 | ring->current_slot = old_top_slot; |
1222 | ring->used_slots = old_used_slots; | 1227 | ring->used_slots = old_used_slots; |
1223 | err = -ENOMEM; | 1228 | err = -ENOMEM; |
1224 | goto out_unmap_hdr; | 1229 | goto out_unmap_hdr; |
1225 | } | 1230 | } |
1231 | memcpy(priv_info->bouncebuffer, skb->data, skb->len); | ||
1226 | 1232 | ||
1227 | memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len); | 1233 | meta->dmaaddr = map_descbuffer(ring, priv_info->bouncebuffer, skb->len, 1); |
1228 | memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb)); | ||
1229 | bounce_skb->dev = skb->dev; | ||
1230 | skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb)); | ||
1231 | info = IEEE80211_SKB_CB(bounce_skb); | ||
1232 | |||
1233 | dev_kfree_skb_any(skb); | ||
1234 | skb = bounce_skb; | ||
1235 | *in_skb = bounce_skb; | ||
1236 | meta->skb = skb; | ||
1237 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | ||
1238 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { | 1234 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
1235 | kfree(priv_info->bouncebuffer); | ||
1236 | priv_info->bouncebuffer = NULL; | ||
1239 | ring->current_slot = old_top_slot; | 1237 | ring->current_slot = old_top_slot; |
1240 | ring->used_slots = old_used_slots; | 1238 | ring->used_slots = old_used_slots; |
1241 | err = -EIO; | 1239 | err = -EIO; |
1242 | goto out_free_bounce; | 1240 | goto out_unmap_hdr; |
1243 | } | 1241 | } |
1244 | } | 1242 | } |
1245 | 1243 | ||
@@ -1256,8 +1254,6 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1256 | ops->poke_tx(ring, next_slot(ring, slot)); | 1254 | ops->poke_tx(ring, next_slot(ring, slot)); |
1257 | return 0; | 1255 | return 0; |
1258 | 1256 | ||
1259 | out_free_bounce: | ||
1260 | dev_kfree_skb_any(skb); | ||
1261 | out_unmap_hdr: | 1257 | out_unmap_hdr: |
1262 | unmap_descbuffer(ring, meta_hdr->dmaaddr, | 1258 | unmap_descbuffer(ring, meta_hdr->dmaaddr, |
1263 | hdrsize, 1); | 1259 | hdrsize, 1); |
@@ -1362,11 +1358,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) | |||
1362 | * static, so we don't need to store it per frame. */ | 1358 | * static, so we don't need to store it per frame. */ |
1363 | ring->queue_prio = skb_get_queue_mapping(skb); | 1359 | ring->queue_prio = skb_get_queue_mapping(skb); |
1364 | 1360 | ||
1365 | /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing | 1361 | err = dma_tx_fragment(ring, skb); |
1366 | * into the skb data or cb now. */ | ||
1367 | hdr = NULL; | ||
1368 | info = NULL; | ||
1369 | err = dma_tx_fragment(ring, &skb); | ||
1370 | if (unlikely(err == -ENOKEY)) { | 1362 | if (unlikely(err == -ENOKEY)) { |
1371 | /* Drop this packet, as we don't have the encryption key | 1363 | /* Drop this packet, as we don't have the encryption key |
1372 | * anymore and must not transmit it unencrypted. */ | 1364 | * anymore and must not transmit it unencrypted. */ |
@@ -1378,7 +1370,6 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) | |||
1378 | b43err(dev->wl, "DMA tx mapping failure\n"); | 1370 | b43err(dev->wl, "DMA tx mapping failure\n"); |
1379 | goto out; | 1371 | goto out; |
1380 | } | 1372 | } |
1381 | ring->nr_tx_packets++; | ||
1382 | if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || | 1373 | if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || |
1383 | should_inject_overflow(ring)) { | 1374 | should_inject_overflow(ring)) { |
1384 | /* This TX ring is full. */ | 1375 | /* This TX ring is full. */ |
@@ -1400,30 +1391,63 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1400 | struct b43_dmaring *ring; | 1391 | struct b43_dmaring *ring; |
1401 | struct b43_dmadesc_generic *desc; | 1392 | struct b43_dmadesc_generic *desc; |
1402 | struct b43_dmadesc_meta *meta; | 1393 | struct b43_dmadesc_meta *meta; |
1403 | int slot; | 1394 | int slot, firstused; |
1404 | bool frame_succeed; | 1395 | bool frame_succeed; |
1405 | 1396 | ||
1406 | ring = parse_cookie(dev, status->cookie, &slot); | 1397 | ring = parse_cookie(dev, status->cookie, &slot); |
1407 | if (unlikely(!ring)) | 1398 | if (unlikely(!ring)) |
1408 | return; | 1399 | return; |
1409 | |||
1410 | B43_WARN_ON(!ring->tx); | 1400 | B43_WARN_ON(!ring->tx); |
1401 | |||
1402 | /* Sanity check: TX packets are processed in-order on one ring. | ||
1403 | * Check if the slot deduced from the cookie really is the first | ||
1404 | * used slot. */ | ||
1405 | firstused = ring->current_slot - ring->used_slots + 1; | ||
1406 | if (firstused < 0) | ||
1407 | firstused = ring->nr_slots + firstused; | ||
1408 | if (unlikely(slot != firstused)) { | ||
1409 | /* This possibly is a firmware bug and will result in | ||
1410 | * malfunction, memory leaks and/or stall of DMA functionality. */ | ||
1411 | b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. " | ||
1412 | "Expected %d, but got %d\n", | ||
1413 | ring->index, firstused, slot); | ||
1414 | return; | ||
1415 | } | ||
1416 | |||
1411 | ops = ring->ops; | 1417 | ops = ring->ops; |
1412 | while (1) { | 1418 | while (1) { |
1413 | B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); | 1419 | B43_WARN_ON(slot < 0 || slot >= ring->nr_slots); |
1414 | desc = ops->idx2desc(ring, slot, &meta); | 1420 | desc = ops->idx2desc(ring, slot, &meta); |
1415 | 1421 | ||
1416 | if (meta->skb) | 1422 | if (b43_dma_ptr_is_poisoned(meta->skb)) { |
1417 | unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, | 1423 | b43dbg(dev->wl, "Poisoned TX slot %d (first=%d) " |
1418 | 1); | 1424 | "on ring %d\n", |
1419 | else | 1425 | slot, firstused, ring->index); |
1426 | break; | ||
1427 | } | ||
1428 | if (meta->skb) { | ||
1429 | struct b43_private_tx_info *priv_info = | ||
1430 | b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); | ||
1431 | |||
1432 | unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); | ||
1433 | kfree(priv_info->bouncebuffer); | ||
1434 | priv_info->bouncebuffer = NULL; | ||
1435 | } else { | ||
1420 | unmap_descbuffer(ring, meta->dmaaddr, | 1436 | unmap_descbuffer(ring, meta->dmaaddr, |
1421 | b43_txhdr_size(dev), 1); | 1437 | b43_txhdr_size(dev), 1); |
1438 | } | ||
1422 | 1439 | ||
1423 | if (meta->is_last_fragment) { | 1440 | if (meta->is_last_fragment) { |
1424 | struct ieee80211_tx_info *info; | 1441 | struct ieee80211_tx_info *info; |
1425 | 1442 | ||
1426 | BUG_ON(!meta->skb); | 1443 | if (unlikely(!meta->skb)) { |
1444 | /* This is a scatter-gather fragment of a frame, so | ||
1445 | * the skb pointer must not be NULL. */ | ||
1446 | b43dbg(dev->wl, "TX status unexpected NULL skb " | ||
1447 | "at slot %d (first=%d) on ring %d\n", | ||
1448 | slot, firstused, ring->index); | ||
1449 | break; | ||
1450 | } | ||
1427 | 1451 | ||
1428 | info = IEEE80211_SKB_CB(meta->skb); | 1452 | info = IEEE80211_SKB_CB(meta->skb); |
1429 | 1453 | ||
@@ -1441,20 +1465,29 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1441 | #endif /* DEBUG */ | 1465 | #endif /* DEBUG */ |
1442 | ieee80211_tx_status(dev->wl->hw, meta->skb); | 1466 | ieee80211_tx_status(dev->wl->hw, meta->skb); |
1443 | 1467 | ||
1444 | /* skb is freed by ieee80211_tx_status() */ | 1468 | /* skb will be freed by ieee80211_tx_status(). |
1445 | meta->skb = NULL; | 1469 | * Poison our pointer. */ |
1470 | meta->skb = B43_DMA_PTR_POISON; | ||
1446 | } else { | 1471 | } else { |
1447 | /* No need to call free_descriptor_buffer here, as | 1472 | /* No need to call free_descriptor_buffer here, as |
1448 | * this is only the txhdr, which is not allocated. | 1473 | * this is only the txhdr, which is not allocated. |
1449 | */ | 1474 | */ |
1450 | B43_WARN_ON(meta->skb); | 1475 | if (unlikely(meta->skb)) { |
1476 | b43dbg(dev->wl, "TX status unexpected non-NULL skb " | ||
1477 | "at slot %d (first=%d) on ring %d\n", | ||
1478 | slot, firstused, ring->index); | ||
1479 | break; | ||
1480 | } | ||
1451 | } | 1481 | } |
1452 | 1482 | ||
1453 | /* Everything unmapped and free'd. So it's not used anymore. */ | 1483 | /* Everything unmapped and free'd. So it's not used anymore. */ |
1454 | ring->used_slots--; | 1484 | ring->used_slots--; |
1455 | 1485 | ||
1456 | if (meta->is_last_fragment) | 1486 | if (meta->is_last_fragment) { |
1487 | /* This is the last scatter-gather | ||
1488 | * fragment of the frame. We are done. */ | ||
1457 | break; | 1489 | break; |
1490 | } | ||
1458 | slot = next_slot(ring, slot); | 1491 | slot = next_slot(ring, slot); |
1459 | } | 1492 | } |
1460 | if (ring->stopped) { | 1493 | if (ring->stopped) { |
@@ -1467,22 +1500,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1467 | } | 1500 | } |
1468 | } | 1501 | } |
1469 | 1502 | ||
1470 | void b43_dma_get_tx_stats(struct b43_wldev *dev, | ||
1471 | struct ieee80211_tx_queue_stats *stats) | ||
1472 | { | ||
1473 | const int nr_queues = dev->wl->hw->queues; | ||
1474 | struct b43_dmaring *ring; | ||
1475 | int i; | ||
1476 | |||
1477 | for (i = 0; i < nr_queues; i++) { | ||
1478 | ring = select_ring_by_priority(dev, i); | ||
1479 | |||
1480 | stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME; | ||
1481 | stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME; | ||
1482 | stats[i].count = ring->nr_tx_packets; | ||
1483 | } | ||
1484 | } | ||
1485 | |||
1486 | static void dma_rx(struct b43_dmaring *ring, int *slot) | 1503 | static void dma_rx(struct b43_dmaring *ring, int *slot) |
1487 | { | 1504 | { |
1488 | const struct b43_dma_ops *ops = ring->ops; | 1505 | const struct b43_dma_ops *ops = ring->ops; |
@@ -1620,7 +1637,6 @@ void b43_dma_tx_resume(struct b43_wldev *dev) | |||
1620 | b43_power_saving_ctl_bits(dev, 0); | 1637 | b43_power_saving_ctl_bits(dev, 0); |
1621 | } | 1638 | } |
1622 | 1639 | ||
1623 | #ifdef CONFIG_B43_PIO | ||
1624 | static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type, | 1640 | static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type, |
1625 | u16 mmio_base, bool enable) | 1641 | u16 mmio_base, bool enable) |
1626 | { | 1642 | { |
@@ -1654,4 +1670,3 @@ void b43_dma_direct_fifo_rx(struct b43_wldev *dev, | |||
1654 | mmio_base = b43_dmacontroller_base(type, engine_index); | 1670 | mmio_base = b43_dmacontroller_base(type, engine_index); |
1655 | direct_fifo_rx(dev, type, mmio_base, enable); | 1671 | direct_fifo_rx(dev, type, mmio_base, enable); |
1656 | } | 1672 | } |
1657 | #endif /* CONFIG_B43_PIO */ | ||
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index f0b0838fb5ba..dc91944d6022 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef B43_DMA_H_ | 1 | #ifndef B43_DMA_H_ |
2 | #define B43_DMA_H_ | 2 | #define B43_DMA_H_ |
3 | 3 | ||
4 | #include <linux/ieee80211.h> | 4 | #include <linux/err.h> |
5 | 5 | ||
6 | #include "b43.h" | 6 | #include "b43.h" |
7 | 7 | ||
@@ -165,6 +165,10 @@ struct b43_dmadesc_generic { | |||
165 | #define B43_RXRING_SLOTS 64 | 165 | #define B43_RXRING_SLOTS 64 |
166 | #define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN | 166 | #define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN |
167 | 167 | ||
168 | /* Pointer poison */ | ||
169 | #define B43_DMA_PTR_POISON ((void *)ERR_PTR(-ENOMEM)) | ||
170 | #define b43_dma_ptr_is_poisoned(ptr) (unlikely((ptr) == B43_DMA_PTR_POISON)) | ||
171 | |||
168 | 172 | ||
169 | struct sk_buff; | 173 | struct sk_buff; |
170 | struct b43_private; | 174 | struct b43_private; |
@@ -224,8 +228,6 @@ struct b43_dmaring { | |||
224 | int used_slots; | 228 | int used_slots; |
225 | /* Currently used slot in the ring. */ | 229 | /* Currently used slot in the ring. */ |
226 | int current_slot; | 230 | int current_slot; |
227 | /* Total number of packets sent. Statistics only. */ | ||
228 | unsigned int nr_tx_packets; | ||
229 | /* Frameoffset in octets. */ | 231 | /* Frameoffset in octets. */ |
230 | u32 frameoffset; | 232 | u32 frameoffset; |
231 | /* Descriptor buffer size. */ | 233 | /* Descriptor buffer size. */ |
@@ -274,9 +276,6 @@ void b43_dma_free(struct b43_wldev *dev); | |||
274 | void b43_dma_tx_suspend(struct b43_wldev *dev); | 276 | void b43_dma_tx_suspend(struct b43_wldev *dev); |
275 | void b43_dma_tx_resume(struct b43_wldev *dev); | 277 | void b43_dma_tx_resume(struct b43_wldev *dev); |
276 | 278 | ||
277 | void b43_dma_get_tx_stats(struct b43_wldev *dev, | ||
278 | struct ieee80211_tx_queue_stats *stats); | ||
279 | |||
280 | int b43_dma_tx(struct b43_wldev *dev, | 279 | int b43_dma_tx(struct b43_wldev *dev, |
281 | struct sk_buff *skb); | 280 | struct sk_buff *skb); |
282 | 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/leds.c b/drivers/net/wireless/b43/leds.c index 1e8dba488004..c587115dd2b9 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c | |||
@@ -246,6 +246,7 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, | |||
246 | *behaviour = B43_LED_OFF; | 246 | *behaviour = B43_LED_OFF; |
247 | break; | 247 | break; |
248 | default: | 248 | default: |
249 | *behaviour = B43_LED_OFF; | ||
249 | B43_WARN_ON(1); | 250 | B43_WARN_ON(1); |
250 | return; | 251 | return; |
251 | } | 252 | } |
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index 976104f634a1..94e4f1378fc3 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
37 | #include <linux/slab.h> | ||
37 | 38 | ||
38 | 39 | ||
39 | static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo, | 40 | static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo, |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 098dda1a67c1..9a374ef83a22 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/skbuff.h> | 42 | #include <linux/skbuff.h> |
43 | #include <linux/io.h> | 43 | #include <linux/io.h> |
44 | #include <linux/dma-mapping.h> | 44 | #include <linux/dma-mapping.h> |
45 | #include <linux/slab.h> | ||
45 | #include <asm/unaligned.h> | 46 | #include <asm/unaligned.h> |
46 | 47 | ||
47 | #include "b43.h" | 48 | #include "b43.h" |
@@ -67,7 +68,12 @@ MODULE_AUTHOR("Gábor Stefanik"); | |||
67 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
68 | 69 | ||
69 | MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); | 70 | MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); |
70 | 71 | MODULE_FIRMWARE("b43/ucode11.fw"); | |
72 | MODULE_FIRMWARE("b43/ucode13.fw"); | ||
73 | MODULE_FIRMWARE("b43/ucode14.fw"); | ||
74 | MODULE_FIRMWARE("b43/ucode15.fw"); | ||
75 | MODULE_FIRMWARE("b43/ucode5.fw"); | ||
76 | MODULE_FIRMWARE("b43/ucode9.fw"); | ||
71 | 77 | ||
72 | static int modparam_bad_frames_preempt; | 78 | static int modparam_bad_frames_preempt; |
73 | module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); | 79 | module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); |
@@ -102,6 +108,9 @@ int b43_modparam_verbose = B43_VERBOSITY_DEFAULT; | |||
102 | module_param_named(verbose, b43_modparam_verbose, int, 0644); | 108 | module_param_named(verbose, b43_modparam_verbose, int, 0644); |
103 | MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); | 109 | MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); |
104 | 110 | ||
111 | int b43_modparam_pio = B43_PIO_DEFAULT; | ||
112 | module_param_named(pio, b43_modparam_pio, int, 0644); | ||
113 | MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); | ||
105 | 114 | ||
106 | static const struct ssb_device_id b43_ssb_tbl[] = { | 115 | static const struct ssb_device_id b43_ssb_tbl[] = { |
107 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), | 116 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), |
@@ -110,6 +119,7 @@ static const struct ssb_device_id b43_ssb_tbl[] = { | |||
110 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9), | 119 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9), |
111 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10), | 120 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10), |
112 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11), | 121 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11), |
122 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 12), | ||
113 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13), | 123 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13), |
114 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15), | 124 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15), |
115 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), | 125 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), |
@@ -628,10 +638,17 @@ static void b43_upload_card_macaddress(struct b43_wldev *dev) | |||
628 | static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) | 638 | static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) |
629 | { | 639 | { |
630 | /* slot_time is in usec. */ | 640 | /* slot_time is in usec. */ |
631 | if (dev->phy.type != B43_PHYTYPE_G) | 641 | /* This test used to exit for all but a G PHY. */ |
642 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
632 | return; | 643 | return; |
633 | b43_write16(dev, 0x684, 510 + slot_time); | 644 | b43_write16(dev, B43_MMIO_IFSSLOT, 510 + slot_time); |
634 | b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time); | 645 | /* Shared memory location 0x0010 is the slot time and should be |
646 | * set to slot_time; however, this register is initially 0 and changing | ||
647 | * the value adversely affects the transmit rate for BCM4311 | ||
648 | * devices. Until this behavior is unterstood, delete this step | ||
649 | * | ||
650 | * b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time); | ||
651 | */ | ||
635 | } | 652 | } |
636 | 653 | ||
637 | static void b43_short_slot_timing_enable(struct b43_wldev *dev) | 654 | static void b43_short_slot_timing_enable(struct b43_wldev *dev) |
@@ -835,8 +852,10 @@ static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32, | |||
835 | } | 852 | } |
836 | 853 | ||
837 | static void b43_op_update_tkip_key(struct ieee80211_hw *hw, | 854 | static void b43_op_update_tkip_key(struct ieee80211_hw *hw, |
838 | struct ieee80211_key_conf *keyconf, const u8 *addr, | 855 | struct ieee80211_vif *vif, |
839 | u32 iv32, u16 *phase1key) | 856 | struct ieee80211_key_conf *keyconf, |
857 | struct ieee80211_sta *sta, | ||
858 | u32 iv32, u16 *phase1key) | ||
840 | { | 859 | { |
841 | struct b43_wl *wl = hw_to_b43_wl(hw); | 860 | struct b43_wl *wl = hw_to_b43_wl(hw); |
842 | struct b43_wldev *dev; | 861 | struct b43_wldev *dev; |
@@ -845,19 +864,19 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw, | |||
845 | if (B43_WARN_ON(!modparam_hwtkip)) | 864 | if (B43_WARN_ON(!modparam_hwtkip)) |
846 | return; | 865 | return; |
847 | 866 | ||
848 | mutex_lock(&wl->mutex); | 867 | /* This is only called from the RX path through mac80211, where |
849 | 868 | * our mutex is already locked. */ | |
869 | B43_WARN_ON(!mutex_is_locked(&wl->mutex)); | ||
850 | dev = wl->current_dev; | 870 | dev = wl->current_dev; |
851 | if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) | 871 | B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED); |
852 | goto out_unlock; | ||
853 | 872 | ||
854 | keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ | 873 | keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ |
855 | 874 | ||
856 | rx_tkip_phase1_write(dev, index, iv32, phase1key); | 875 | rx_tkip_phase1_write(dev, index, iv32, phase1key); |
857 | keymac_write(dev, index, addr); | 876 | /* only pairwise TKIP keys are supported right now */ |
858 | 877 | if (WARN_ON(!sta)) | |
859 | out_unlock: | 878 | return; |
860 | mutex_unlock(&wl->mutex); | 879 | keymac_write(dev, index, sta->addr); |
861 | } | 880 | } |
862 | 881 | ||
863 | static void do_key_write(struct b43_wldev *dev, | 882 | static void do_key_write(struct b43_wldev *dev, |
@@ -1784,6 +1803,10 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) | |||
1784 | dma_reason[0], dma_reason[1], | 1803 | dma_reason[0], dma_reason[1], |
1785 | dma_reason[2], dma_reason[3], | 1804 | dma_reason[2], dma_reason[3], |
1786 | dma_reason[4], dma_reason[5]); | 1805 | dma_reason[4], dma_reason[5]); |
1806 | b43err(dev->wl, "This device does not support DMA " | ||
1807 | "on your system. Please use PIO instead.\n"); | ||
1808 | /* Fall back to PIO transfers if we get fatal DMA errors! */ | ||
1809 | dev->use_pio = 1; | ||
1787 | b43_controller_restart(dev, "DMA error"); | 1810 | b43_controller_restart(dev, "DMA error"); |
1788 | return; | 1811 | return; |
1789 | } | 1812 | } |
@@ -2955,7 +2978,7 @@ static void do_periodic_work(struct b43_wldev *dev) | |||
2955 | /* Periodic work locking policy: | 2978 | /* Periodic work locking policy: |
2956 | * The whole periodic work handler is protected by | 2979 | * The whole periodic work handler is protected by |
2957 | * wl->mutex. If another lock is needed somewhere in the | 2980 | * wl->mutex. If another lock is needed somewhere in the |
2958 | * pwork callchain, it's aquired in-place, where it's needed. | 2981 | * pwork callchain, it's acquired in-place, where it's needed. |
2959 | */ | 2982 | */ |
2960 | static void b43_periodic_work_handler(struct work_struct *work) | 2983 | static void b43_periodic_work_handler(struct work_struct *work) |
2961 | { | 2984 | { |
@@ -3335,27 +3358,6 @@ out_unlock: | |||
3335 | return err; | 3358 | return err; |
3336 | } | 3359 | } |
3337 | 3360 | ||
3338 | static int b43_op_get_tx_stats(struct ieee80211_hw *hw, | ||
3339 | struct ieee80211_tx_queue_stats *stats) | ||
3340 | { | ||
3341 | struct b43_wl *wl = hw_to_b43_wl(hw); | ||
3342 | struct b43_wldev *dev; | ||
3343 | int err = -ENODEV; | ||
3344 | |||
3345 | mutex_lock(&wl->mutex); | ||
3346 | dev = wl->current_dev; | ||
3347 | if (dev && b43_status(dev) >= B43_STAT_STARTED) { | ||
3348 | if (b43_using_pio_transfers(dev)) | ||
3349 | b43_pio_get_tx_stats(dev, stats); | ||
3350 | else | ||
3351 | b43_dma_get_tx_stats(dev, stats); | ||
3352 | err = 0; | ||
3353 | } | ||
3354 | mutex_unlock(&wl->mutex); | ||
3355 | |||
3356 | return err; | ||
3357 | } | ||
3358 | |||
3359 | static int b43_op_get_stats(struct ieee80211_hw *hw, | 3361 | static int b43_op_get_stats(struct ieee80211_hw *hw, |
3360 | struct ieee80211_low_level_stats *stats) | 3362 | struct ieee80211_low_level_stats *stats) |
3361 | { | 3363 | { |
@@ -3559,6 +3561,12 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3559 | dev = wl->current_dev; | 3561 | dev = wl->current_dev; |
3560 | phy = &dev->phy; | 3562 | phy = &dev->phy; |
3561 | 3563 | ||
3564 | if (conf_is_ht(conf)) | ||
3565 | phy->is_40mhz = | ||
3566 | (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf)); | ||
3567 | else | ||
3568 | phy->is_40mhz = false; | ||
3569 | |||
3562 | b43_mac_suspend(dev); | 3570 | b43_mac_suspend(dev); |
3563 | 3571 | ||
3564 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) | 3572 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) |
@@ -3573,7 +3581,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3573 | if (conf->channel->hw_value != phy->channel) | 3581 | if (conf->channel->hw_value != phy->channel) |
3574 | b43_switch_channel(dev, conf->channel->hw_value); | 3582 | b43_switch_channel(dev, conf->channel->hw_value); |
3575 | 3583 | ||
3576 | dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 3584 | dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); |
3577 | 3585 | ||
3578 | /* Adjust the desired TX power level. */ | 3586 | /* Adjust the desired TX power level. */ |
3579 | if (conf->power_level != 0) { | 3587 | if (conf->power_level != 0) { |
@@ -3960,6 +3968,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev) | |||
3960 | } | 3968 | } |
3961 | 3969 | ||
3962 | /* We are ready to run. */ | 3970 | /* We are ready to run. */ |
3971 | ieee80211_wake_queues(dev->wl->hw); | ||
3963 | b43_set_status(dev, B43_STAT_STARTED); | 3972 | b43_set_status(dev, B43_STAT_STARTED); |
3964 | 3973 | ||
3965 | /* Start data flow (TX/RX). */ | 3974 | /* Start data flow (TX/RX). */ |
@@ -4350,7 +4359,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4350 | 4359 | ||
4351 | if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || | 4360 | if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || |
4352 | (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) || | 4361 | (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) || |
4353 | B43_FORCE_PIO) { | 4362 | dev->use_pio) { |
4354 | dev->__using_pio_transfers = 1; | 4363 | dev->__using_pio_transfers = 1; |
4355 | err = b43_pio_init(dev); | 4364 | err = b43_pio_init(dev); |
4356 | } else { | 4365 | } else { |
@@ -4369,8 +4378,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4369 | 4378 | ||
4370 | ieee80211_wake_queues(dev->wl->hw); | 4379 | ieee80211_wake_queues(dev->wl->hw); |
4371 | 4380 | ||
4372 | ieee80211_wake_queues(dev->wl->hw); | ||
4373 | |||
4374 | b43_set_status(dev, B43_STAT_INITIALIZED); | 4381 | b43_set_status(dev, B43_STAT_INITIALIZED); |
4375 | 4382 | ||
4376 | out: | 4383 | out: |
@@ -4385,7 +4392,7 @@ err_busdown: | |||
4385 | } | 4392 | } |
4386 | 4393 | ||
4387 | static int b43_op_add_interface(struct ieee80211_hw *hw, | 4394 | static int b43_op_add_interface(struct ieee80211_hw *hw, |
4388 | struct ieee80211_if_init_conf *conf) | 4395 | struct ieee80211_vif *vif) |
4389 | { | 4396 | { |
4390 | struct b43_wl *wl = hw_to_b43_wl(hw); | 4397 | struct b43_wl *wl = hw_to_b43_wl(hw); |
4391 | struct b43_wldev *dev; | 4398 | struct b43_wldev *dev; |
@@ -4393,24 +4400,24 @@ static int b43_op_add_interface(struct ieee80211_hw *hw, | |||
4393 | 4400 | ||
4394 | /* TODO: allow WDS/AP devices to coexist */ | 4401 | /* TODO: allow WDS/AP devices to coexist */ |
4395 | 4402 | ||
4396 | if (conf->type != NL80211_IFTYPE_AP && | 4403 | if (vif->type != NL80211_IFTYPE_AP && |
4397 | conf->type != NL80211_IFTYPE_MESH_POINT && | 4404 | vif->type != NL80211_IFTYPE_MESH_POINT && |
4398 | conf->type != NL80211_IFTYPE_STATION && | 4405 | vif->type != NL80211_IFTYPE_STATION && |
4399 | conf->type != NL80211_IFTYPE_WDS && | 4406 | vif->type != NL80211_IFTYPE_WDS && |
4400 | conf->type != NL80211_IFTYPE_ADHOC) | 4407 | vif->type != NL80211_IFTYPE_ADHOC) |
4401 | return -EOPNOTSUPP; | 4408 | return -EOPNOTSUPP; |
4402 | 4409 | ||
4403 | mutex_lock(&wl->mutex); | 4410 | mutex_lock(&wl->mutex); |
4404 | if (wl->operating) | 4411 | if (wl->operating) |
4405 | goto out_mutex_unlock; | 4412 | goto out_mutex_unlock; |
4406 | 4413 | ||
4407 | b43dbg(wl, "Adding Interface type %d\n", conf->type); | 4414 | b43dbg(wl, "Adding Interface type %d\n", vif->type); |
4408 | 4415 | ||
4409 | dev = wl->current_dev; | 4416 | dev = wl->current_dev; |
4410 | wl->operating = 1; | 4417 | wl->operating = 1; |
4411 | wl->vif = conf->vif; | 4418 | wl->vif = vif; |
4412 | wl->if_type = conf->type; | 4419 | wl->if_type = vif->type; |
4413 | memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN); | 4420 | memcpy(wl->mac_addr, vif->addr, ETH_ALEN); |
4414 | 4421 | ||
4415 | b43_adjust_opmode(dev); | 4422 | b43_adjust_opmode(dev); |
4416 | b43_set_pretbtt(dev); | 4423 | b43_set_pretbtt(dev); |
@@ -4425,17 +4432,17 @@ static int b43_op_add_interface(struct ieee80211_hw *hw, | |||
4425 | } | 4432 | } |
4426 | 4433 | ||
4427 | static void b43_op_remove_interface(struct ieee80211_hw *hw, | 4434 | static void b43_op_remove_interface(struct ieee80211_hw *hw, |
4428 | struct ieee80211_if_init_conf *conf) | 4435 | struct ieee80211_vif *vif) |
4429 | { | 4436 | { |
4430 | struct b43_wl *wl = hw_to_b43_wl(hw); | 4437 | struct b43_wl *wl = hw_to_b43_wl(hw); |
4431 | struct b43_wldev *dev = wl->current_dev; | 4438 | struct b43_wldev *dev = wl->current_dev; |
4432 | 4439 | ||
4433 | b43dbg(wl, "Removing Interface type %d\n", conf->type); | 4440 | b43dbg(wl, "Removing Interface type %d\n", vif->type); |
4434 | 4441 | ||
4435 | mutex_lock(&wl->mutex); | 4442 | mutex_lock(&wl->mutex); |
4436 | 4443 | ||
4437 | B43_WARN_ON(!wl->operating); | 4444 | B43_WARN_ON(!wl->operating); |
4438 | B43_WARN_ON(wl->vif != conf->vif); | 4445 | B43_WARN_ON(wl->vif != vif); |
4439 | wl->vif = NULL; | 4446 | wl->vif = NULL; |
4440 | 4447 | ||
4441 | wl->operating = 0; | 4448 | wl->operating = 0; |
@@ -4576,7 +4583,6 @@ static const struct ieee80211_ops b43_hw_ops = { | |||
4576 | .set_key = b43_op_set_key, | 4583 | .set_key = b43_op_set_key, |
4577 | .update_tkip_key = b43_op_update_tkip_key, | 4584 | .update_tkip_key = b43_op_update_tkip_key, |
4578 | .get_stats = b43_op_get_stats, | 4585 | .get_stats = b43_op_get_stats, |
4579 | .get_tx_stats = b43_op_get_tx_stats, | ||
4580 | .get_tsf = b43_op_get_tsf, | 4586 | .get_tsf = b43_op_get_tsf, |
4581 | .set_tsf = b43_op_set_tsf, | 4587 | .set_tsf = b43_op_set_tsf, |
4582 | .start = b43_op_start, | 4588 | .start = b43_op_start, |
@@ -4669,7 +4675,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4669 | { | 4675 | { |
4670 | struct b43_wl *wl = dev->wl; | 4676 | struct b43_wl *wl = dev->wl; |
4671 | struct ssb_bus *bus = dev->dev->bus; | 4677 | struct ssb_bus *bus = dev->dev->bus; |
4672 | struct pci_dev *pdev = bus->host_pci; | 4678 | struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; |
4673 | int err; | 4679 | int err; |
4674 | bool have_2ghz_phy = 0, have_5ghz_phy = 0; | 4680 | bool have_2ghz_phy = 0, have_5ghz_phy = 0; |
4675 | u32 tmp; | 4681 | u32 tmp; |
@@ -4802,7 +4808,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) | |||
4802 | 4808 | ||
4803 | if (!list_empty(&wl->devlist)) { | 4809 | if (!list_empty(&wl->devlist)) { |
4804 | /* We are not the first core on this chip. */ | 4810 | /* We are not the first core on this chip. */ |
4805 | pdev = dev->bus->host_pci; | 4811 | pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL; |
4806 | /* Only special chips support more than one wireless | 4812 | /* Only special chips support more than one wireless |
4807 | * core, although some of the other chips have more than | 4813 | * core, although some of the other chips have more than |
4808 | * one wireless core as well. Check for this and | 4814 | * one wireless core as well. Check for this and |
@@ -4820,6 +4826,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) | |||
4820 | if (!wldev) | 4826 | if (!wldev) |
4821 | goto out; | 4827 | goto out; |
4822 | 4828 | ||
4829 | wldev->use_pio = b43_modparam_pio; | ||
4823 | wldev->dev = dev; | 4830 | wldev->dev = dev; |
4824 | wldev->wl = wl; | 4831 | wldev->wl = wl; |
4825 | b43_set_status(wldev, B43_STAT_UNINIT); | 4832 | b43_set_status(wldev, B43_STAT_UNINIT); |
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 6c3a74964ab8..609e7051e018 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "pcmcia.h" | 24 | #include "pcmcia.h" |
25 | 25 | ||
26 | #include <linux/ssb/ssb.h> | 26 | #include <linux/ssb/ssb.h> |
27 | #include <linux/slab.h> | ||
27 | 28 | ||
28 | #include <pcmcia/cs_types.h> | 29 | #include <pcmcia/cs_types.h> |
29 | #include <pcmcia/cs.h> | 30 | #include <pcmcia/cs.h> |
@@ -65,35 +66,15 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) | |||
65 | struct ssb_bus *ssb; | 66 | struct ssb_bus *ssb; |
66 | win_req_t win; | 67 | win_req_t win; |
67 | memreq_t mem; | 68 | memreq_t mem; |
68 | tuple_t tuple; | ||
69 | cisparse_t parse; | ||
70 | int err = -ENOMEM; | 69 | int err = -ENOMEM; |
71 | int res = 0; | 70 | int res = 0; |
72 | unsigned char buf[64]; | ||
73 | 71 | ||
74 | ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); | 72 | ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); |
75 | if (!ssb) | 73 | if (!ssb) |
76 | goto out_error; | 74 | goto out_error; |
77 | 75 | ||
78 | err = -ENODEV; | 76 | err = -ENODEV; |
79 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
80 | tuple.Attributes = 0; | ||
81 | tuple.TupleData = buf; | ||
82 | tuple.TupleDataMax = sizeof(buf); | ||
83 | tuple.TupleOffset = 0; | ||
84 | 77 | ||
85 | res = pcmcia_get_first_tuple(dev, &tuple); | ||
86 | if (res != 0) | ||
87 | goto err_kfree_ssb; | ||
88 | res = pcmcia_get_tuple_data(dev, &tuple); | ||
89 | if (res != 0) | ||
90 | goto err_kfree_ssb; | ||
91 | res = pcmcia_parse_tuple(&tuple, &parse); | ||
92 | if (res != 0) | ||
93 | goto err_kfree_ssb; | ||
94 | |||
95 | dev->conf.ConfigBase = parse.config.base; | ||
96 | dev->conf.Present = parse.config.rmask[0]; | ||
97 | dev->conf.Attributes = CONF_ENABLE_IRQ; | 78 | dev->conf.Attributes = CONF_ENABLE_IRQ; |
98 | dev->conf.IntType = INT_MEMORY_AND_IO; | 79 | dev->conf.IntType = INT_MEMORY_AND_IO; |
99 | 80 | ||
@@ -107,20 +88,18 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) | |||
107 | win.Base = 0; | 88 | win.Base = 0; |
108 | win.Size = SSB_CORE_SIZE; | 89 | win.Size = SSB_CORE_SIZE; |
109 | win.AccessSpeed = 250; | 90 | win.AccessSpeed = 250; |
110 | res = pcmcia_request_window(&dev, &win, &dev->win); | 91 | res = pcmcia_request_window(dev, &win, &dev->win); |
111 | if (res != 0) | 92 | if (res != 0) |
112 | goto err_kfree_ssb; | 93 | goto err_kfree_ssb; |
113 | 94 | ||
114 | mem.CardOffset = 0; | 95 | mem.CardOffset = 0; |
115 | mem.Page = 0; | 96 | mem.Page = 0; |
116 | res = pcmcia_map_mem_page(dev->win, &mem); | 97 | res = pcmcia_map_mem_page(dev, dev->win, &mem); |
117 | if (res != 0) | 98 | if (res != 0) |
118 | goto err_disable; | 99 | goto err_disable; |
119 | 100 | ||
120 | dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | 101 | dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; |
121 | dev->irq.IRQInfo1 = IRQ_LEVEL_ID; | ||
122 | dev->irq.Handler = NULL; /* The handler is registered later. */ | 102 | dev->irq.Handler = NULL; /* The handler is registered later. */ |
123 | dev->irq.Instance = NULL; | ||
124 | res = pcmcia_request_irq(dev, &dev->irq); | 103 | res = pcmcia_request_irq(dev, &dev->irq); |
125 | if (res != 0) | 104 | if (res != 0) |
126 | goto err_disable; | 105 | goto err_disable; |
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index d90217c3a706..b6428ec16dd6 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c | |||
@@ -26,6 +26,8 @@ | |||
26 | 26 | ||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/slab.h> | ||
30 | |||
29 | #include "b43.h" | 31 | #include "b43.h" |
30 | #include "phy_a.h" | 32 | #include "phy_a.h" |
31 | #include "phy_common.h" | 33 | #include "phy_common.h" |
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 75b26e175e8f..8f7d7eff2d80 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -421,3 +421,48 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on) | |||
421 | { | 421 | { |
422 | b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); | 422 | b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); |
423 | } | 423 | } |
424 | |||
425 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */ | ||
426 | struct b43_c32 b43_cordic(int theta) | ||
427 | { | ||
428 | u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304, | ||
429 | 58666, 29335, 14668, 7334, 3667, 1833, 917, 458, | ||
430 | 229, 115, 57, 29, }; | ||
431 | u8 i; | ||
432 | s32 tmp; | ||
433 | s8 signx = 1; | ||
434 | u32 angle = 0; | ||
435 | struct b43_c32 ret = { .i = 39797, .q = 0, }; | ||
436 | |||
437 | while (theta > (180 << 16)) | ||
438 | theta -= (360 << 16); | ||
439 | while (theta < -(180 << 16)) | ||
440 | theta += (360 << 16); | ||
441 | |||
442 | if (theta > (90 << 16)) { | ||
443 | theta -= (180 << 16); | ||
444 | signx = -1; | ||
445 | } else if (theta < -(90 << 16)) { | ||
446 | theta += (180 << 16); | ||
447 | signx = -1; | ||
448 | } | ||
449 | |||
450 | for (i = 0; i <= 17; i++) { | ||
451 | if (theta > angle) { | ||
452 | tmp = ret.i - (ret.q >> i); | ||
453 | ret.q += ret.i >> i; | ||
454 | ret.i = tmp; | ||
455 | angle += arctg[i]; | ||
456 | } else { | ||
457 | tmp = ret.i + (ret.q >> i); | ||
458 | ret.q -= ret.i >> i; | ||
459 | ret.i = tmp; | ||
460 | angle -= arctg[i]; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | ret.i *= signx; | ||
465 | ret.q *= signx; | ||
466 | |||
467 | return ret; | ||
468 | } | ||
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 9edd4e8e0c85..bd480b481bfc 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h | |||
@@ -5,6 +5,12 @@ | |||
5 | 5 | ||
6 | struct b43_wldev; | 6 | struct b43_wldev; |
7 | 7 | ||
8 | /* Complex number using 2 32-bit signed integers */ | ||
9 | struct b43_c32 { s32 i, q; }; | ||
10 | |||
11 | #define CORDIC_CONVERT(value) (((value) >= 0) ? \ | ||
12 | ((((value) >> 15) + 1) >> 1) : \ | ||
13 | -((((-(value)) >> 15) + 1) >> 1)) | ||
8 | 14 | ||
9 | /* PHY register routing bits */ | 15 | /* PHY register routing bits */ |
10 | #define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */ | 16 | #define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */ |
@@ -212,6 +218,9 @@ struct b43_phy { | |||
212 | bool supports_2ghz; | 218 | bool supports_2ghz; |
213 | bool supports_5ghz; | 219 | bool supports_5ghz; |
214 | 220 | ||
221 | /* HT info */ | ||
222 | bool is_40mhz; | ||
223 | |||
215 | /* GMODE bit enabled? */ | 224 | /* GMODE bit enabled? */ |
216 | bool gmode; | 225 | bool gmode; |
217 | 226 | ||
@@ -418,5 +427,6 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset); | |||
418 | */ | 427 | */ |
419 | void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); | 428 | void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); |
420 | 429 | ||
430 | struct b43_c32 b43_cordic(int theta); | ||
421 | 431 | ||
422 | #endif /* LINUX_B43_PHY_COMMON_H_ */ | 432 | #endif /* LINUX_B43_PHY_COMMON_H_ */ |
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 382826a8da82..29bf34ced865 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "main.h" | 33 | #include "main.h" |
34 | 34 | ||
35 | #include <linux/bitrev.h> | 35 | #include <linux/bitrev.h> |
36 | #include <linux/slab.h> | ||
36 | 37 | ||
37 | 38 | ||
38 | static const s8 b43_tssi2dbm_g_table[] = { | 39 | static const s8 b43_tssi2dbm_g_table[] = { |
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 1e318d815a5b..c6afe9d94590 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/slab.h> | ||
27 | |||
26 | #include "b43.h" | 28 | #include "b43.h" |
27 | #include "main.h" | 29 | #include "main.h" |
28 | #include "phy_lp.h" | 30 | #include "phy_lp.h" |
@@ -67,6 +69,7 @@ static void b43_lpphy_op_prepare_structs(struct b43_wldev *dev) | |||
67 | struct b43_phy_lp *lpphy = phy->lp; | 69 | struct b43_phy_lp *lpphy = phy->lp; |
68 | 70 | ||
69 | memset(lpphy, 0, sizeof(*lpphy)); | 71 | memset(lpphy, 0, sizeof(*lpphy)); |
72 | lpphy->antenna = B43_ANTENNA_DEFAULT; | ||
70 | 73 | ||
71 | //TODO | 74 | //TODO |
72 | } | 75 | } |
@@ -79,6 +82,7 @@ static void b43_lpphy_op_free(struct b43_wldev *dev) | |||
79 | dev->phy.lp = NULL; | 82 | dev->phy.lp = NULL; |
80 | } | 83 | } |
81 | 84 | ||
85 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */ | ||
82 | static void lpphy_read_band_sprom(struct b43_wldev *dev) | 86 | static void lpphy_read_band_sprom(struct b43_wldev *dev) |
83 | { | 87 | { |
84 | struct b43_phy_lp *lpphy = dev->phy.lp; | 88 | struct b43_phy_lp *lpphy = dev->phy.lp; |
@@ -100,6 +104,12 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev) | |||
100 | maxpwr = bus->sprom.maxpwr_bg; | 104 | maxpwr = bus->sprom.maxpwr_bg; |
101 | lpphy->max_tx_pwr_med_band = maxpwr; | 105 | lpphy->max_tx_pwr_med_band = maxpwr; |
102 | cckpo = bus->sprom.cck2gpo; | 106 | cckpo = bus->sprom.cck2gpo; |
107 | /* | ||
108 | * We don't read SPROM's opo as specs say. On rev8 SPROMs | ||
109 | * opo == ofdm2gpo and we don't know any SSB with LP-PHY | ||
110 | * and SPROM rev below 8. | ||
111 | */ | ||
112 | B43_WARN_ON(bus->sprom.revision < 8); | ||
103 | ofdmpo = bus->sprom.ofdm2gpo; | 113 | ofdmpo = bus->sprom.ofdm2gpo; |
104 | if (cckpo) { | 114 | if (cckpo) { |
105 | for (i = 0; i < 4; i++) { | 115 | for (i = 0; i < 4; i++) { |
@@ -751,11 +761,17 @@ static void lpphy_clear_deaf(struct b43_wldev *dev, bool user) | |||
751 | } | 761 | } |
752 | } | 762 | } |
753 | 763 | ||
764 | static void lpphy_set_trsw_over(struct b43_wldev *dev, bool tx, bool rx) | ||
765 | { | ||
766 | u16 trsw = (tx << 1) | rx; | ||
767 | b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, trsw); | ||
768 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3); | ||
769 | } | ||
770 | |||
754 | static void lpphy_disable_crs(struct b43_wldev *dev, bool user) | 771 | static void lpphy_disable_crs(struct b43_wldev *dev, bool user) |
755 | { | 772 | { |
756 | lpphy_set_deaf(dev, user); | 773 | lpphy_set_deaf(dev, user); |
757 | b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1); | 774 | lpphy_set_trsw_over(dev, false, true); |
758 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3); | ||
759 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB); | 775 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB); |
760 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x4); | 776 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x4); |
761 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFF7); | 777 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFF7); |
@@ -790,6 +806,60 @@ static void lpphy_restore_crs(struct b43_wldev *dev, bool user) | |||
790 | 806 | ||
791 | struct lpphy_tx_gains { u16 gm, pga, pad, dac; }; | 807 | struct lpphy_tx_gains { u16 gm, pga, pad, dac; }; |
792 | 808 | ||
809 | static void lpphy_disable_rx_gain_override(struct b43_wldev *dev) | ||
810 | { | ||
811 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE); | ||
812 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF); | ||
813 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF); | ||
814 | if (dev->phy.rev >= 2) { | ||
815 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF); | ||
816 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
817 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF); | ||
818 | b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7); | ||
819 | } | ||
820 | } else { | ||
821 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF); | ||
822 | } | ||
823 | } | ||
824 | |||
825 | static void lpphy_enable_rx_gain_override(struct b43_wldev *dev) | ||
826 | { | ||
827 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1); | ||
828 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10); | ||
829 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40); | ||
830 | if (dev->phy.rev >= 2) { | ||
831 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100); | ||
832 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
833 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400); | ||
834 | b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8); | ||
835 | } | ||
836 | } else { | ||
837 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200); | ||
838 | } | ||
839 | } | ||
840 | |||
841 | static void lpphy_disable_tx_gain_override(struct b43_wldev *dev) | ||
842 | { | ||
843 | if (dev->phy.rev < 2) | ||
844 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF); | ||
845 | else { | ||
846 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F); | ||
847 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF); | ||
848 | } | ||
849 | b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF); | ||
850 | } | ||
851 | |||
852 | static void lpphy_enable_tx_gain_override(struct b43_wldev *dev) | ||
853 | { | ||
854 | if (dev->phy.rev < 2) | ||
855 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100); | ||
856 | else { | ||
857 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x80); | ||
858 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x4000); | ||
859 | } | ||
860 | b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 0x40); | ||
861 | } | ||
862 | |||
793 | static struct lpphy_tx_gains lpphy_get_tx_gains(struct b43_wldev *dev) | 863 | static struct lpphy_tx_gains lpphy_get_tx_gains(struct b43_wldev *dev) |
794 | { | 864 | { |
795 | struct lpphy_tx_gains gains; | 865 | struct lpphy_tx_gains gains; |
@@ -819,6 +889,17 @@ static void lpphy_set_dac_gain(struct b43_wldev *dev, u16 dac) | |||
819 | b43_phy_maskset(dev, B43_LPPHY_AFE_DAC_CTL, 0xF000, ctl); | 889 | b43_phy_maskset(dev, B43_LPPHY_AFE_DAC_CTL, 0xF000, ctl); |
820 | } | 890 | } |
821 | 891 | ||
892 | static u16 lpphy_get_pa_gain(struct b43_wldev *dev) | ||
893 | { | ||
894 | return b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x7F; | ||
895 | } | ||
896 | |||
897 | static void lpphy_set_pa_gain(struct b43_wldev *dev, u16 gain) | ||
898 | { | ||
899 | b43_phy_maskset(dev, B43_PHY_OFDM(0xFB), 0xE03F, gain << 6); | ||
900 | b43_phy_maskset(dev, B43_PHY_OFDM(0xFD), 0x80FF, gain << 8); | ||
901 | } | ||
902 | |||
822 | static void lpphy_set_tx_gains(struct b43_wldev *dev, | 903 | static void lpphy_set_tx_gains(struct b43_wldev *dev, |
823 | struct lpphy_tx_gains gains) | 904 | struct lpphy_tx_gains gains) |
824 | { | 905 | { |
@@ -829,25 +910,22 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev, | |||
829 | b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, | 910 | b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, |
830 | 0xF800, rf_gain); | 911 | 0xF800, rf_gain); |
831 | } else { | 912 | } else { |
832 | pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x1FC0; | 913 | pa_gain = lpphy_get_pa_gain(dev); |
833 | pa_gain <<= 2; | ||
834 | b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, | 914 | b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, |
835 | (gains.pga << 8) | gains.gm); | 915 | (gains.pga << 8) | gains.gm); |
916 | /* | ||
917 | * SPEC FIXME The spec calls for (pa_gain << 8) here, but that | ||
918 | * conflicts with the spec for set_pa_gain! Vendor driver bug? | ||
919 | */ | ||
836 | b43_phy_maskset(dev, B43_PHY_OFDM(0xFB), | 920 | b43_phy_maskset(dev, B43_PHY_OFDM(0xFB), |
837 | 0x8000, gains.pad | pa_gain); | 921 | 0x8000, gains.pad | (pa_gain << 6)); |
838 | b43_phy_write(dev, B43_PHY_OFDM(0xFC), | 922 | b43_phy_write(dev, B43_PHY_OFDM(0xFC), |
839 | (gains.pga << 8) | gains.gm); | 923 | (gains.pga << 8) | gains.gm); |
840 | b43_phy_maskset(dev, B43_PHY_OFDM(0xFD), | 924 | b43_phy_maskset(dev, B43_PHY_OFDM(0xFD), |
841 | 0x8000, gains.pad | pa_gain); | 925 | 0x8000, gains.pad | (pa_gain << 8)); |
842 | } | 926 | } |
843 | lpphy_set_dac_gain(dev, gains.dac); | 927 | lpphy_set_dac_gain(dev, gains.dac); |
844 | if (dev->phy.rev < 2) { | 928 | lpphy_enable_tx_gain_override(dev); |
845 | b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF, 1 << 8); | ||
846 | } else { | ||
847 | b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7); | ||
848 | b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14); | ||
849 | } | ||
850 | b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF, 1 << 6); | ||
851 | } | 929 | } |
852 | 930 | ||
853 | static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain) | 931 | static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain) |
@@ -887,38 +965,6 @@ static void lpphy_rev2plus_set_rx_gain(struct b43_wldev *dev, u32 gain) | |||
887 | } | 965 | } |
888 | } | 966 | } |
889 | 967 | ||
890 | static void lpphy_disable_rx_gain_override(struct b43_wldev *dev) | ||
891 | { | ||
892 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE); | ||
893 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF); | ||
894 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF); | ||
895 | if (dev->phy.rev >= 2) { | ||
896 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF); | ||
897 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
898 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF); | ||
899 | b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7); | ||
900 | } | ||
901 | } else { | ||
902 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF); | ||
903 | } | ||
904 | } | ||
905 | |||
906 | static void lpphy_enable_rx_gain_override(struct b43_wldev *dev) | ||
907 | { | ||
908 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1); | ||
909 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10); | ||
910 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40); | ||
911 | if (dev->phy.rev >= 2) { | ||
912 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100); | ||
913 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
914 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400); | ||
915 | b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8); | ||
916 | } | ||
917 | } else { | ||
918 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200); | ||
919 | } | ||
920 | } | ||
921 | |||
922 | static void lpphy_set_rx_gain(struct b43_wldev *dev, u32 gain) | 968 | static void lpphy_set_rx_gain(struct b43_wldev *dev, u32 gain) |
923 | { | 969 | { |
924 | if (dev->phy.rev < 2) | 970 | if (dev->phy.rev < 2) |
@@ -1003,8 +1049,7 @@ static int lpphy_loopback(struct b43_wldev *dev) | |||
1003 | 1049 | ||
1004 | memset(&iq_est, 0, sizeof(iq_est)); | 1050 | memset(&iq_est, 0, sizeof(iq_est)); |
1005 | 1051 | ||
1006 | b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x3); | 1052 | lpphy_set_trsw_over(dev, true, true); |
1007 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3); | ||
1008 | b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 1); | 1053 | b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 1); |
1009 | b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE); | 1054 | b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE); |
1010 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800); | 1055 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800); |
@@ -1126,7 +1171,7 @@ static void lpphy_set_tx_power_control(struct b43_wldev *dev, | |||
1126 | b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM, | 1171 | b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM, |
1127 | 0x8FFF, ((u16)lpphy->tssi_npt << 16)); | 1172 | 0x8FFF, ((u16)lpphy->tssi_npt << 16)); |
1128 | //TODO Set "TSSI Transmit Count" variable to total transmitted frame count | 1173 | //TODO Set "TSSI Transmit Count" variable to total transmitted frame count |
1129 | //TODO Disable TX gain override | 1174 | lpphy_disable_tx_gain_override(dev); |
1130 | lpphy->tx_pwr_idx_over = -1; | 1175 | lpphy->tx_pwr_idx_over = -1; |
1131 | } | 1176 | } |
1132 | } | 1177 | } |
@@ -1312,15 +1357,73 @@ static void lpphy_calibrate_rc(struct b43_wldev *dev) | |||
1312 | } | 1357 | } |
1313 | } | 1358 | } |
1314 | 1359 | ||
1360 | static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) | ||
1361 | { | ||
1362 | if (dev->phy.rev >= 2) | ||
1363 | return; // rev2+ doesn't support antenna diversity | ||
1364 | |||
1365 | if (B43_WARN_ON(antenna > B43_ANTENNA_AUTO1)) | ||
1366 | return; | ||
1367 | |||
1368 | b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP); | ||
1369 | |||
1370 | b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFD, antenna & 0x2); | ||
1371 | b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFE, antenna & 0x1); | ||
1372 | |||
1373 | b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP); | ||
1374 | |||
1375 | dev->phy.lp->antenna = antenna; | ||
1376 | } | ||
1377 | |||
1378 | static void lpphy_set_tx_iqcc(struct b43_wldev *dev, u16 a, u16 b) | ||
1379 | { | ||
1380 | u16 tmp[2]; | ||
1381 | |||
1382 | tmp[0] = a; | ||
1383 | tmp[1] = b; | ||
1384 | b43_lptab_write_bulk(dev, B43_LPTAB16(0, 80), 2, tmp); | ||
1385 | } | ||
1386 | |||
1315 | static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index) | 1387 | static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index) |
1316 | { | 1388 | { |
1317 | struct b43_phy_lp *lpphy = dev->phy.lp; | 1389 | struct b43_phy_lp *lpphy = dev->phy.lp; |
1390 | struct lpphy_tx_gains gains; | ||
1391 | u32 iq_comp, tx_gain, coeff, rf_power; | ||
1318 | 1392 | ||
1319 | lpphy->tx_pwr_idx_over = index; | 1393 | lpphy->tx_pwr_idx_over = index; |
1394 | lpphy_read_tx_pctl_mode_from_hardware(dev); | ||
1320 | if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF) | 1395 | if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF) |
1321 | lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW); | 1396 | lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW); |
1322 | 1397 | if (dev->phy.rev >= 2) { | |
1323 | //TODO | 1398 | iq_comp = b43_lptab_read(dev, B43_LPTAB32(7, index + 320)); |
1399 | tx_gain = b43_lptab_read(dev, B43_LPTAB32(7, index + 192)); | ||
1400 | gains.pad = (tx_gain >> 16) & 0xFF; | ||
1401 | gains.gm = tx_gain & 0xFF; | ||
1402 | gains.pga = (tx_gain >> 8) & 0xFF; | ||
1403 | gains.dac = (iq_comp >> 28) & 0xFF; | ||
1404 | lpphy_set_tx_gains(dev, gains); | ||
1405 | } else { | ||
1406 | iq_comp = b43_lptab_read(dev, B43_LPTAB32(10, index + 320)); | ||
1407 | tx_gain = b43_lptab_read(dev, B43_LPTAB32(10, index + 192)); | ||
1408 | b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, | ||
1409 | 0xF800, (tx_gain >> 4) & 0x7FFF); | ||
1410 | lpphy_set_dac_gain(dev, tx_gain & 0x7); | ||
1411 | lpphy_set_pa_gain(dev, (tx_gain >> 24) & 0x7F); | ||
1412 | } | ||
1413 | lpphy_set_bb_mult(dev, (iq_comp >> 20) & 0xFF); | ||
1414 | lpphy_set_tx_iqcc(dev, (iq_comp >> 10) & 0x3FF, iq_comp & 0x3FF); | ||
1415 | if (dev->phy.rev >= 2) { | ||
1416 | coeff = b43_lptab_read(dev, B43_LPTAB32(7, index + 448)); | ||
1417 | } else { | ||
1418 | coeff = b43_lptab_read(dev, B43_LPTAB32(10, index + 448)); | ||
1419 | } | ||
1420 | b43_lptab_write(dev, B43_LPTAB16(0, 85), coeff & 0xFFFF); | ||
1421 | if (dev->phy.rev >= 2) { | ||
1422 | rf_power = b43_lptab_read(dev, B43_LPTAB32(7, index + 576)); | ||
1423 | b43_phy_maskset(dev, B43_LPPHY_RF_PWR_OVERRIDE, 0xFF00, | ||
1424 | rf_power & 0xFFFF);//SPEC FIXME mask & set != 0 | ||
1425 | } | ||
1426 | lpphy_enable_tx_gain_override(dev); | ||
1324 | } | 1427 | } |
1325 | 1428 | ||
1326 | static void lpphy_btcoex_override(struct b43_wldev *dev) | 1429 | static void lpphy_btcoex_override(struct b43_wldev *dev) |
@@ -1329,58 +1432,45 @@ static void lpphy_btcoex_override(struct b43_wldev *dev) | |||
1329 | b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF); | 1432 | b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF); |
1330 | } | 1433 | } |
1331 | 1434 | ||
1332 | static void lpphy_pr41573_workaround(struct b43_wldev *dev) | 1435 | static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, |
1436 | bool blocked) | ||
1333 | { | 1437 | { |
1334 | struct b43_phy_lp *lpphy = dev->phy.lp; | 1438 | //TODO check MAC control register |
1335 | u32 *saved_tab; | 1439 | if (blocked) { |
1336 | const unsigned int saved_tab_size = 256; | 1440 | if (dev->phy.rev >= 2) { |
1337 | enum b43_lpphy_txpctl_mode txpctl_mode; | 1441 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x83FF); |
1338 | s8 tx_pwr_idx_over; | 1442 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1F00); |
1339 | u16 tssi_npt, tssi_idx; | 1443 | b43_phy_mask(dev, B43_LPPHY_AFE_DDFS, 0x80FF); |
1340 | 1444 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xDFFF); | |
1341 | saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL); | 1445 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x0808); |
1342 | if (!saved_tab) { | 1446 | } else { |
1343 | b43err(dev->wl, "PR41573 failed. Out of memory!\n"); | 1447 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xE0FF); |
1344 | return; | 1448 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1F00); |
1345 | } | 1449 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFCFF); |
1346 | 1450 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x0018); | |
1347 | lpphy_read_tx_pctl_mode_from_hardware(dev); | 1451 | } |
1348 | txpctl_mode = lpphy->txpctl_mode; | ||
1349 | tx_pwr_idx_over = lpphy->tx_pwr_idx_over; | ||
1350 | tssi_npt = lpphy->tssi_npt; | ||
1351 | tssi_idx = lpphy->tssi_idx; | ||
1352 | |||
1353 | if (dev->phy.rev < 2) { | ||
1354 | b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140), | ||
1355 | saved_tab_size, saved_tab); | ||
1356 | } else { | 1452 | } else { |
1357 | b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140), | 1453 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xE0FF); |
1358 | saved_tab_size, saved_tab); | 1454 | if (dev->phy.rev >= 2) |
1455 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xF7F7); | ||
1456 | else | ||
1457 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFE7); | ||
1359 | } | 1458 | } |
1360 | //TODO | ||
1361 | |||
1362 | kfree(saved_tab); | ||
1363 | } | 1459 | } |
1364 | 1460 | ||
1365 | static void lpphy_calibration(struct b43_wldev *dev) | 1461 | /* This was previously called lpphy_japan_filter */ |
1462 | static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel) | ||
1366 | { | 1463 | { |
1367 | struct b43_phy_lp *lpphy = dev->phy.lp; | 1464 | struct b43_phy_lp *lpphy = dev->phy.lp; |
1368 | enum b43_lpphy_txpctl_mode saved_pctl_mode; | 1465 | u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter! |
1369 | |||
1370 | b43_mac_suspend(dev); | ||
1371 | |||
1372 | lpphy_btcoex_override(dev); | ||
1373 | lpphy_read_tx_pctl_mode_from_hardware(dev); | ||
1374 | saved_pctl_mode = lpphy->txpctl_mode; | ||
1375 | lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); | ||
1376 | //TODO Perform transmit power table I/Q LO calibration | ||
1377 | if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF)) | ||
1378 | lpphy_pr41573_workaround(dev); | ||
1379 | //TODO If a full calibration has not been performed on this channel yet, perform PAPD TX-power calibration | ||
1380 | lpphy_set_tx_power_control(dev, saved_pctl_mode); | ||
1381 | //TODO Perform I/Q calibration with a single control value set | ||
1382 | 1466 | ||
1383 | b43_mac_enable(dev); | 1467 | if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific? |
1468 | b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9); | ||
1469 | if ((dev->phy.rev == 1) && (lpphy->rc_cap)) | ||
1470 | lpphy_set_rc_cap(dev); | ||
1471 | } else { | ||
1472 | b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F); | ||
1473 | } | ||
1384 | } | 1474 | } |
1385 | 1475 | ||
1386 | static void lpphy_set_tssi_mux(struct b43_wldev *dev, enum tssi_mux_mode mode) | 1476 | static void lpphy_set_tssi_mux(struct b43_wldev *dev, enum tssi_mux_mode mode) |
@@ -1489,6 +1579,420 @@ static void lpphy_tx_pctl_init(struct b43_wldev *dev) | |||
1489 | } | 1579 | } |
1490 | } | 1580 | } |
1491 | 1581 | ||
1582 | static void lpphy_pr41573_workaround(struct b43_wldev *dev) | ||
1583 | { | ||
1584 | struct b43_phy_lp *lpphy = dev->phy.lp; | ||
1585 | u32 *saved_tab; | ||
1586 | const unsigned int saved_tab_size = 256; | ||
1587 | enum b43_lpphy_txpctl_mode txpctl_mode; | ||
1588 | s8 tx_pwr_idx_over; | ||
1589 | u16 tssi_npt, tssi_idx; | ||
1590 | |||
1591 | saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL); | ||
1592 | if (!saved_tab) { | ||
1593 | b43err(dev->wl, "PR41573 failed. Out of memory!\n"); | ||
1594 | return; | ||
1595 | } | ||
1596 | |||
1597 | lpphy_read_tx_pctl_mode_from_hardware(dev); | ||
1598 | txpctl_mode = lpphy->txpctl_mode; | ||
1599 | tx_pwr_idx_over = lpphy->tx_pwr_idx_over; | ||
1600 | tssi_npt = lpphy->tssi_npt; | ||
1601 | tssi_idx = lpphy->tssi_idx; | ||
1602 | |||
1603 | if (dev->phy.rev < 2) { | ||
1604 | b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140), | ||
1605 | saved_tab_size, saved_tab); | ||
1606 | } else { | ||
1607 | b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140), | ||
1608 | saved_tab_size, saved_tab); | ||
1609 | } | ||
1610 | //FIXME PHY reset | ||
1611 | lpphy_table_init(dev); //FIXME is table init needed? | ||
1612 | lpphy_baseband_init(dev); | ||
1613 | lpphy_tx_pctl_init(dev); | ||
1614 | b43_lpphy_op_software_rfkill(dev, false); | ||
1615 | lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); | ||
1616 | if (dev->phy.rev < 2) { | ||
1617 | b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0x140), | ||
1618 | saved_tab_size, saved_tab); | ||
1619 | } else { | ||
1620 | b43_lptab_write_bulk(dev, B43_LPTAB32(7, 0x140), | ||
1621 | saved_tab_size, saved_tab); | ||
1622 | } | ||
1623 | b43_write16(dev, B43_MMIO_CHANNEL, lpphy->channel); | ||
1624 | lpphy->tssi_npt = tssi_npt; | ||
1625 | lpphy->tssi_idx = tssi_idx; | ||
1626 | lpphy_set_analog_filter(dev, lpphy->channel); | ||
1627 | if (tx_pwr_idx_over != -1) | ||
1628 | lpphy_set_tx_power_by_index(dev, tx_pwr_idx_over); | ||
1629 | if (lpphy->rc_cap) | ||
1630 | lpphy_set_rc_cap(dev); | ||
1631 | b43_lpphy_op_set_rx_antenna(dev, lpphy->antenna); | ||
1632 | lpphy_set_tx_power_control(dev, txpctl_mode); | ||
1633 | kfree(saved_tab); | ||
1634 | } | ||
1635 | |||
1636 | struct lpphy_rx_iq_comp { u8 chan; s8 c1, c0; }; | ||
1637 | |||
1638 | static const struct lpphy_rx_iq_comp lpphy_5354_iq_table[] = { | ||
1639 | { .chan = 1, .c1 = -66, .c0 = 15, }, | ||
1640 | { .chan = 2, .c1 = -66, .c0 = 15, }, | ||
1641 | { .chan = 3, .c1 = -66, .c0 = 15, }, | ||
1642 | { .chan = 4, .c1 = -66, .c0 = 15, }, | ||
1643 | { .chan = 5, .c1 = -66, .c0 = 15, }, | ||
1644 | { .chan = 6, .c1 = -66, .c0 = 15, }, | ||
1645 | { .chan = 7, .c1 = -66, .c0 = 14, }, | ||
1646 | { .chan = 8, .c1 = -66, .c0 = 14, }, | ||
1647 | { .chan = 9, .c1 = -66, .c0 = 14, }, | ||
1648 | { .chan = 10, .c1 = -66, .c0 = 14, }, | ||
1649 | { .chan = 11, .c1 = -66, .c0 = 14, }, | ||
1650 | { .chan = 12, .c1 = -66, .c0 = 13, }, | ||
1651 | { .chan = 13, .c1 = -66, .c0 = 13, }, | ||
1652 | { .chan = 14, .c1 = -66, .c0 = 13, }, | ||
1653 | }; | ||
1654 | |||
1655 | static const struct lpphy_rx_iq_comp lpphy_rev0_1_iq_table[] = { | ||
1656 | { .chan = 1, .c1 = -64, .c0 = 13, }, | ||
1657 | { .chan = 2, .c1 = -64, .c0 = 13, }, | ||
1658 | { .chan = 3, .c1 = -64, .c0 = 13, }, | ||
1659 | { .chan = 4, .c1 = -64, .c0 = 13, }, | ||
1660 | { .chan = 5, .c1 = -64, .c0 = 12, }, | ||
1661 | { .chan = 6, .c1 = -64, .c0 = 12, }, | ||
1662 | { .chan = 7, .c1 = -64, .c0 = 12, }, | ||
1663 | { .chan = 8, .c1 = -64, .c0 = 12, }, | ||
1664 | { .chan = 9, .c1 = -64, .c0 = 12, }, | ||
1665 | { .chan = 10, .c1 = -64, .c0 = 11, }, | ||
1666 | { .chan = 11, .c1 = -64, .c0 = 11, }, | ||
1667 | { .chan = 12, .c1 = -64, .c0 = 11, }, | ||
1668 | { .chan = 13, .c1 = -64, .c0 = 11, }, | ||
1669 | { .chan = 14, .c1 = -64, .c0 = 10, }, | ||
1670 | { .chan = 34, .c1 = -62, .c0 = 24, }, | ||
1671 | { .chan = 38, .c1 = -62, .c0 = 24, }, | ||
1672 | { .chan = 42, .c1 = -62, .c0 = 24, }, | ||
1673 | { .chan = 46, .c1 = -62, .c0 = 23, }, | ||
1674 | { .chan = 36, .c1 = -62, .c0 = 24, }, | ||
1675 | { .chan = 40, .c1 = -62, .c0 = 24, }, | ||
1676 | { .chan = 44, .c1 = -62, .c0 = 23, }, | ||
1677 | { .chan = 48, .c1 = -62, .c0 = 23, }, | ||
1678 | { .chan = 52, .c1 = -62, .c0 = 23, }, | ||
1679 | { .chan = 56, .c1 = -62, .c0 = 22, }, | ||
1680 | { .chan = 60, .c1 = -62, .c0 = 22, }, | ||
1681 | { .chan = 64, .c1 = -62, .c0 = 22, }, | ||
1682 | { .chan = 100, .c1 = -62, .c0 = 16, }, | ||
1683 | { .chan = 104, .c1 = -62, .c0 = 16, }, | ||
1684 | { .chan = 108, .c1 = -62, .c0 = 15, }, | ||
1685 | { .chan = 112, .c1 = -62, .c0 = 14, }, | ||
1686 | { .chan = 116, .c1 = -62, .c0 = 14, }, | ||
1687 | { .chan = 120, .c1 = -62, .c0 = 13, }, | ||
1688 | { .chan = 124, .c1 = -62, .c0 = 12, }, | ||
1689 | { .chan = 128, .c1 = -62, .c0 = 12, }, | ||
1690 | { .chan = 132, .c1 = -62, .c0 = 12, }, | ||
1691 | { .chan = 136, .c1 = -62, .c0 = 11, }, | ||
1692 | { .chan = 140, .c1 = -62, .c0 = 10, }, | ||
1693 | { .chan = 149, .c1 = -61, .c0 = 9, }, | ||
1694 | { .chan = 153, .c1 = -61, .c0 = 9, }, | ||
1695 | { .chan = 157, .c1 = -61, .c0 = 9, }, | ||
1696 | { .chan = 161, .c1 = -61, .c0 = 8, }, | ||
1697 | { .chan = 165, .c1 = -61, .c0 = 8, }, | ||
1698 | { .chan = 184, .c1 = -62, .c0 = 25, }, | ||
1699 | { .chan = 188, .c1 = -62, .c0 = 25, }, | ||
1700 | { .chan = 192, .c1 = -62, .c0 = 25, }, | ||
1701 | { .chan = 196, .c1 = -62, .c0 = 25, }, | ||
1702 | { .chan = 200, .c1 = -62, .c0 = 25, }, | ||
1703 | { .chan = 204, .c1 = -62, .c0 = 25, }, | ||
1704 | { .chan = 208, .c1 = -62, .c0 = 25, }, | ||
1705 | { .chan = 212, .c1 = -62, .c0 = 25, }, | ||
1706 | { .chan = 216, .c1 = -62, .c0 = 26, }, | ||
1707 | }; | ||
1708 | |||
1709 | static const struct lpphy_rx_iq_comp lpphy_rev2plus_iq_comp = { | ||
1710 | .chan = 0, | ||
1711 | .c1 = -64, | ||
1712 | .c0 = 0, | ||
1713 | }; | ||
1714 | |||
1715 | static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples) | ||
1716 | { | ||
1717 | struct lpphy_iq_est iq_est; | ||
1718 | u16 c0, c1; | ||
1719 | int prod, ipwr, qpwr, prod_msb, q_msb, tmp1, tmp2, tmp3, tmp4, ret; | ||
1720 | |||
1721 | c1 = b43_phy_read(dev, B43_LPPHY_RX_COMP_COEFF_S); | ||
1722 | c0 = c1 >> 8; | ||
1723 | c1 |= 0xFF; | ||
1724 | |||
1725 | b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, 0x00C0); | ||
1726 | b43_phy_mask(dev, B43_LPPHY_RX_COMP_COEFF_S, 0x00FF); | ||
1727 | |||
1728 | ret = lpphy_rx_iq_est(dev, samples, 32, &iq_est); | ||
1729 | if (!ret) | ||
1730 | goto out; | ||
1731 | |||
1732 | prod = iq_est.iq_prod; | ||
1733 | ipwr = iq_est.i_pwr; | ||
1734 | qpwr = iq_est.q_pwr; | ||
1735 | |||
1736 | if (ipwr + qpwr < 2) { | ||
1737 | ret = 0; | ||
1738 | goto out; | ||
1739 | } | ||
1740 | |||
1741 | prod_msb = fls(abs(prod)); | ||
1742 | q_msb = fls(abs(qpwr)); | ||
1743 | tmp1 = prod_msb - 20; | ||
1744 | |||
1745 | if (tmp1 >= 0) { | ||
1746 | tmp3 = ((prod << (30 - prod_msb)) + (ipwr >> (1 + tmp1))) / | ||
1747 | (ipwr >> tmp1); | ||
1748 | } else { | ||
1749 | tmp3 = ((prod << (30 - prod_msb)) + (ipwr << (-1 - tmp1))) / | ||
1750 | (ipwr << -tmp1); | ||
1751 | } | ||
1752 | |||
1753 | tmp2 = q_msb - 11; | ||
1754 | |||
1755 | if (tmp2 >= 0) | ||
1756 | tmp4 = (qpwr << (31 - q_msb)) / (ipwr >> tmp2); | ||
1757 | else | ||
1758 | tmp4 = (qpwr << (31 - q_msb)) / (ipwr << -tmp2); | ||
1759 | |||
1760 | tmp4 -= tmp3 * tmp3; | ||
1761 | tmp4 = -int_sqrt(tmp4); | ||
1762 | |||
1763 | c0 = tmp3 >> 3; | ||
1764 | c1 = tmp4 >> 4; | ||
1765 | |||
1766 | out: | ||
1767 | b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, c1); | ||
1768 | b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0x00FF, c0 << 8); | ||
1769 | return ret; | ||
1770 | } | ||
1771 | |||
1772 | static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops, | ||
1773 | u16 wait) | ||
1774 | { | ||
1775 | b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_BUFFER_CTL, | ||
1776 | 0xFFC0, samples - 1); | ||
1777 | if (loops != 0xFFFF) | ||
1778 | loops--; | ||
1779 | b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_COUNT, 0xF000, loops); | ||
1780 | b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_BUFFER_CTL, 0x3F, wait << 6); | ||
1781 | b43_phy_set(dev, B43_LPPHY_A_PHY_CTL_ADDR, 0x1); | ||
1782 | } | ||
1783 | |||
1784 | //SPEC FIXME what does a negative freq mean? | ||
1785 | static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max) | ||
1786 | { | ||
1787 | struct b43_phy_lp *lpphy = dev->phy.lp; | ||
1788 | u16 buf[64]; | ||
1789 | int i, samples = 0, angle = 0; | ||
1790 | int rotation = (((36 * freq) / 20) << 16) / 100; | ||
1791 | struct b43_c32 sample; | ||
1792 | |||
1793 | lpphy->tx_tone_freq = freq; | ||
1794 | |||
1795 | if (freq) { | ||
1796 | /* Find i for which abs(freq) integrally divides 20000 * i */ | ||
1797 | for (i = 1; samples * abs(freq) != 20000 * i; i++) { | ||
1798 | samples = (20000 * i) / abs(freq); | ||
1799 | if(B43_WARN_ON(samples > 63)) | ||
1800 | return; | ||
1801 | } | ||
1802 | } else { | ||
1803 | samples = 2; | ||
1804 | } | ||
1805 | |||
1806 | for (i = 0; i < samples; i++) { | ||
1807 | sample = b43_cordic(angle); | ||
1808 | angle += rotation; | ||
1809 | buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8; | ||
1810 | buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF); | ||
1811 | } | ||
1812 | |||
1813 | b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf); | ||
1814 | |||
1815 | lpphy_run_samples(dev, samples, 0xFFFF, 0); | ||
1816 | } | ||
1817 | |||
1818 | static void lpphy_stop_tx_tone(struct b43_wldev *dev) | ||
1819 | { | ||
1820 | struct b43_phy_lp *lpphy = dev->phy.lp; | ||
1821 | int i; | ||
1822 | |||
1823 | lpphy->tx_tone_freq = 0; | ||
1824 | |||
1825 | b43_phy_mask(dev, B43_LPPHY_SMPL_PLAY_COUNT, 0xF000); | ||
1826 | for (i = 0; i < 31; i++) { | ||
1827 | if (!(b43_phy_read(dev, B43_LPPHY_A_PHY_CTL_ADDR) & 0x1)) | ||
1828 | break; | ||
1829 | udelay(100); | ||
1830 | } | ||
1831 | } | ||
1832 | |||
1833 | |||
1834 | static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains, | ||
1835 | int mode, bool useindex, u8 index) | ||
1836 | { | ||
1837 | //TODO | ||
1838 | } | ||
1839 | |||
1840 | static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) | ||
1841 | { | ||
1842 | struct b43_phy_lp *lpphy = dev->phy.lp; | ||
1843 | struct ssb_bus *bus = dev->dev->bus; | ||
1844 | struct lpphy_tx_gains gains, oldgains; | ||
1845 | int old_txpctl, old_afe_ovr, old_rf, old_bbmult; | ||
1846 | |||
1847 | lpphy_read_tx_pctl_mode_from_hardware(dev); | ||
1848 | old_txpctl = lpphy->txpctl_mode; | ||
1849 | old_afe_ovr = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40; | ||
1850 | if (old_afe_ovr) | ||
1851 | oldgains = lpphy_get_tx_gains(dev); | ||
1852 | old_rf = b43_phy_read(dev, B43_LPPHY_RF_PWR_OVERRIDE) & 0xFF; | ||
1853 | old_bbmult = lpphy_get_bb_mult(dev); | ||
1854 | |||
1855 | lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); | ||
1856 | |||
1857 | if (bus->chip_id == 0x4325 && bus->chip_rev == 0) | ||
1858 | lpphy_papd_cal(dev, gains, 0, 1, 30); | ||
1859 | else | ||
1860 | lpphy_papd_cal(dev, gains, 0, 1, 65); | ||
1861 | |||
1862 | if (old_afe_ovr) | ||
1863 | lpphy_set_tx_gains(dev, oldgains); | ||
1864 | lpphy_set_bb_mult(dev, old_bbmult); | ||
1865 | lpphy_set_tx_power_control(dev, old_txpctl); | ||
1866 | b43_phy_maskset(dev, B43_LPPHY_RF_PWR_OVERRIDE, 0xFF00, old_rf); | ||
1867 | } | ||
1868 | |||
1869 | static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, | ||
1870 | bool rx, bool pa, struct lpphy_tx_gains *gains) | ||
1871 | { | ||
1872 | struct b43_phy_lp *lpphy = dev->phy.lp; | ||
1873 | struct ssb_bus *bus = dev->dev->bus; | ||
1874 | const struct lpphy_rx_iq_comp *iqcomp = NULL; | ||
1875 | struct lpphy_tx_gains nogains, oldgains; | ||
1876 | u16 tmp; | ||
1877 | int i, ret; | ||
1878 | |||
1879 | memset(&nogains, 0, sizeof(nogains)); | ||
1880 | memset(&oldgains, 0, sizeof(oldgains)); | ||
1881 | |||
1882 | if (bus->chip_id == 0x5354) { | ||
1883 | for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) { | ||
1884 | if (lpphy_5354_iq_table[i].chan == lpphy->channel) { | ||
1885 | iqcomp = &lpphy_5354_iq_table[i]; | ||
1886 | } | ||
1887 | } | ||
1888 | } else if (dev->phy.rev >= 2) { | ||
1889 | iqcomp = &lpphy_rev2plus_iq_comp; | ||
1890 | } else { | ||
1891 | for (i = 0; i < ARRAY_SIZE(lpphy_rev0_1_iq_table); i++) { | ||
1892 | if (lpphy_rev0_1_iq_table[i].chan == lpphy->channel) { | ||
1893 | iqcomp = &lpphy_rev0_1_iq_table[i]; | ||
1894 | } | ||
1895 | } | ||
1896 | } | ||
1897 | |||
1898 | if (B43_WARN_ON(!iqcomp)) | ||
1899 | return 0; | ||
1900 | |||
1901 | b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, iqcomp->c1); | ||
1902 | b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, | ||
1903 | 0x00FF, iqcomp->c0 << 8); | ||
1904 | |||
1905 | if (noise) { | ||
1906 | tx = true; | ||
1907 | rx = false; | ||
1908 | pa = false; | ||
1909 | } | ||
1910 | |||
1911 | lpphy_set_trsw_over(dev, tx, rx); | ||
1912 | |||
1913 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
1914 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x8); | ||
1915 | b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, | ||
1916 | 0xFFF7, pa << 3); | ||
1917 | } else { | ||
1918 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x20); | ||
1919 | b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, | ||
1920 | 0xFFDF, pa << 5); | ||
1921 | } | ||
1922 | |||
1923 | tmp = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40; | ||
1924 | |||
1925 | if (noise) | ||
1926 | lpphy_set_rx_gain(dev, 0x2D5D); | ||
1927 | else { | ||
1928 | if (tmp) | ||
1929 | oldgains = lpphy_get_tx_gains(dev); | ||
1930 | if (!gains) | ||
1931 | gains = &nogains; | ||
1932 | lpphy_set_tx_gains(dev, *gains); | ||
1933 | } | ||
1934 | |||
1935 | b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFFE); | ||
1936 | b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE); | ||
1937 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800); | ||
1938 | b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x800); | ||
1939 | lpphy_set_deaf(dev, false); | ||
1940 | if (noise) | ||
1941 | ret = lpphy_calc_rx_iq_comp(dev, 0xFFF0); | ||
1942 | else { | ||
1943 | lpphy_start_tx_tone(dev, 4000, 100); | ||
1944 | ret = lpphy_calc_rx_iq_comp(dev, 0x4000); | ||
1945 | lpphy_stop_tx_tone(dev); | ||
1946 | } | ||
1947 | lpphy_clear_deaf(dev, false); | ||
1948 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFC); | ||
1949 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFF7); | ||
1950 | b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFDF); | ||
1951 | if (!noise) { | ||
1952 | if (tmp) | ||
1953 | lpphy_set_tx_gains(dev, oldgains); | ||
1954 | else | ||
1955 | lpphy_disable_tx_gain_override(dev); | ||
1956 | } | ||
1957 | lpphy_disable_rx_gain_override(dev); | ||
1958 | b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFFE); | ||
1959 | b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xF7FF); | ||
1960 | return ret; | ||
1961 | } | ||
1962 | |||
1963 | static void lpphy_calibration(struct b43_wldev *dev) | ||
1964 | { | ||
1965 | struct b43_phy_lp *lpphy = dev->phy.lp; | ||
1966 | enum b43_lpphy_txpctl_mode saved_pctl_mode; | ||
1967 | bool full_cal = false; | ||
1968 | |||
1969 | if (lpphy->full_calib_chan != lpphy->channel) { | ||
1970 | full_cal = true; | ||
1971 | lpphy->full_calib_chan = lpphy->channel; | ||
1972 | } | ||
1973 | |||
1974 | b43_mac_suspend(dev); | ||
1975 | |||
1976 | lpphy_btcoex_override(dev); | ||
1977 | if (dev->phy.rev >= 2) | ||
1978 | lpphy_save_dig_flt_state(dev); | ||
1979 | lpphy_read_tx_pctl_mode_from_hardware(dev); | ||
1980 | saved_pctl_mode = lpphy->txpctl_mode; | ||
1981 | lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); | ||
1982 | //TODO Perform transmit power table I/Q LO calibration | ||
1983 | if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF)) | ||
1984 | lpphy_pr41573_workaround(dev); | ||
1985 | if ((dev->phy.rev >= 2) && full_cal) { | ||
1986 | lpphy_papd_cal_txpwr(dev); | ||
1987 | } | ||
1988 | lpphy_set_tx_power_control(dev, saved_pctl_mode); | ||
1989 | if (dev->phy.rev >= 2) | ||
1990 | lpphy_restore_dig_flt_state(dev); | ||
1991 | lpphy_rx_iq_cal(dev, true, true, false, false, NULL); | ||
1992 | |||
1993 | b43_mac_enable(dev); | ||
1994 | } | ||
1995 | |||
1492 | static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg) | 1996 | static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg) |
1493 | { | 1997 | { |
1494 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | 1998 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); |
@@ -1533,12 +2037,6 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value) | |||
1533 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); | 2037 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); |
1534 | } | 2038 | } |
1535 | 2039 | ||
1536 | static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, | ||
1537 | bool blocked) | ||
1538 | { | ||
1539 | //TODO | ||
1540 | } | ||
1541 | |||
1542 | struct b206x_channel { | 2040 | struct b206x_channel { |
1543 | u8 channel; | 2041 | u8 channel; |
1544 | u16 freq; | 2042 | u16 freq; |
@@ -2004,22 +2502,6 @@ static int lpphy_b2062_tune(struct b43_wldev *dev, | |||
2004 | return err; | 2502 | return err; |
2005 | } | 2503 | } |
2006 | 2504 | ||
2007 | |||
2008 | /* This was previously called lpphy_japan_filter */ | ||
2009 | static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel) | ||
2010 | { | ||
2011 | struct b43_phy_lp *lpphy = dev->phy.lp; | ||
2012 | u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter! | ||
2013 | |||
2014 | if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific? | ||
2015 | b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9); | ||
2016 | if ((dev->phy.rev == 1) && (lpphy->rc_cap)) | ||
2017 | lpphy_set_rc_cap(dev); | ||
2018 | } else { | ||
2019 | b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F); | ||
2020 | } | ||
2021 | } | ||
2022 | |||
2023 | static void lpphy_b2063_vco_calib(struct b43_wldev *dev) | 2505 | static void lpphy_b2063_vco_calib(struct b43_wldev *dev) |
2024 | { | 2506 | { |
2025 | u16 tmp; | 2507 | u16 tmp; |
@@ -2204,18 +2686,6 @@ static int b43_lpphy_op_init(struct b43_wldev *dev) | |||
2204 | return 0; | 2686 | return 0; |
2205 | } | 2687 | } |
2206 | 2688 | ||
2207 | static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) | ||
2208 | { | ||
2209 | if (dev->phy.rev >= 2) | ||
2210 | return; // rev2+ doesn't support antenna diversity | ||
2211 | |||
2212 | if (B43_WARN_ON(antenna > B43_ANTENNA_AUTO1)) | ||
2213 | return; | ||
2214 | |||
2215 | b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFD, antenna & 0x2); | ||
2216 | b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFE, antenna & 0x1); | ||
2217 | } | ||
2218 | |||
2219 | static void b43_lpphy_op_adjust_txpower(struct b43_wldev *dev) | 2689 | static void b43_lpphy_op_adjust_txpower(struct b43_wldev *dev) |
2220 | { | 2690 | { |
2221 | //TODO | 2691 | //TODO |
@@ -2238,6 +2708,11 @@ void b43_lpphy_op_switch_analog(struct b43_wldev *dev, bool on) | |||
2238 | } | 2708 | } |
2239 | } | 2709 | } |
2240 | 2710 | ||
2711 | static void b43_lpphy_op_pwork_15sec(struct b43_wldev *dev) | ||
2712 | { | ||
2713 | //TODO | ||
2714 | } | ||
2715 | |||
2241 | const struct b43_phy_operations b43_phyops_lp = { | 2716 | const struct b43_phy_operations b43_phyops_lp = { |
2242 | .allocate = b43_lpphy_op_allocate, | 2717 | .allocate = b43_lpphy_op_allocate, |
2243 | .free = b43_lpphy_op_free, | 2718 | .free = b43_lpphy_op_free, |
@@ -2255,4 +2730,6 @@ const struct b43_phy_operations b43_phyops_lp = { | |||
2255 | .set_rx_antenna = b43_lpphy_op_set_rx_antenna, | 2730 | .set_rx_antenna = b43_lpphy_op_set_rx_antenna, |
2256 | .recalc_txpower = b43_lpphy_op_recalc_txpower, | 2731 | .recalc_txpower = b43_lpphy_op_recalc_txpower, |
2257 | .adjust_txpower = b43_lpphy_op_adjust_txpower, | 2732 | .adjust_txpower = b43_lpphy_op_adjust_txpower, |
2733 | .pwork_15sec = b43_lpphy_op_pwork_15sec, | ||
2734 | .pwork_60sec = lpphy_calibration, | ||
2258 | }; | 2735 | }; |
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h index c3232c17b60a..62737f700cbc 100644 --- a/drivers/net/wireless/b43/phy_lp.h +++ b/drivers/net/wireless/b43/phy_lp.h | |||
@@ -286,6 +286,7 @@ | |||
286 | #define B43_LPPHY_TR_LOOKUP_6 B43_PHY_OFDM(0xC8) /* TR Lookup 6 */ | 286 | #define B43_LPPHY_TR_LOOKUP_6 B43_PHY_OFDM(0xC8) /* TR Lookup 6 */ |
287 | #define B43_LPPHY_TR_LOOKUP_7 B43_PHY_OFDM(0xC9) /* TR Lookup 7 */ | 287 | #define B43_LPPHY_TR_LOOKUP_7 B43_PHY_OFDM(0xC9) /* TR Lookup 7 */ |
288 | #define B43_LPPHY_TR_LOOKUP_8 B43_PHY_OFDM(0xCA) /* TR Lookup 8 */ | 288 | #define B43_LPPHY_TR_LOOKUP_8 B43_PHY_OFDM(0xCA) /* TR Lookup 8 */ |
289 | #define B43_LPPHY_RF_PWR_OVERRIDE B43_PHY_OFDM(0xD3) /* RF power override */ | ||
289 | 290 | ||
290 | 291 | ||
291 | 292 | ||
@@ -871,12 +872,12 @@ struct b43_phy_lp { | |||
871 | u8 rssi_gs; | 872 | u8 rssi_gs; |
872 | 873 | ||
873 | /* RC cap */ | 874 | /* RC cap */ |
874 | u8 rc_cap; /* FIXME initial value? */ | 875 | u8 rc_cap; |
875 | /* BX arch */ | 876 | /* BX arch */ |
876 | u8 bx_arch; | 877 | u8 bx_arch; |
877 | 878 | ||
878 | /* Full calibration channel */ | 879 | /* Full calibration channel */ |
879 | u8 full_calib_chan; /* FIXME initial value? */ | 880 | u8 full_calib_chan; |
880 | 881 | ||
881 | /* Transmit iqlocal best coeffs */ | 882 | /* Transmit iqlocal best coeffs */ |
882 | bool tx_iqloc_best_coeffs_valid; | 883 | bool tx_iqloc_best_coeffs_valid; |
@@ -891,6 +892,12 @@ struct b43_phy_lp { | |||
891 | 892 | ||
892 | /* The channel we are tuned to */ | 893 | /* The channel we are tuned to */ |
893 | u8 channel; | 894 | u8 channel; |
895 | |||
896 | /* The active antenna diversity mode */ | ||
897 | int antenna; | ||
898 | |||
899 | /* Frequency of the active TX tone */ | ||
900 | int tx_tone_freq; | ||
894 | }; | 901 | }; |
895 | 902 | ||
896 | enum tssi_mux_mode { | 903 | enum tssi_mux_mode { |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 992318a78077..9c7cd282e46c 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -23,12 +23,56 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/slab.h> | ||
26 | #include <linux/types.h> | 27 | #include <linux/types.h> |
27 | 28 | ||
28 | #include "b43.h" | 29 | #include "b43.h" |
29 | #include "phy_n.h" | 30 | #include "phy_n.h" |
30 | #include "tables_nphy.h" | 31 | #include "tables_nphy.h" |
32 | #include "main.h" | ||
31 | 33 | ||
34 | struct nphy_txgains { | ||
35 | u16 txgm[2]; | ||
36 | u16 pga[2]; | ||
37 | u16 pad[2]; | ||
38 | u16 ipa[2]; | ||
39 | }; | ||
40 | |||
41 | struct nphy_iqcal_params { | ||
42 | u16 txgm; | ||
43 | u16 pga; | ||
44 | u16 pad; | ||
45 | u16 ipa; | ||
46 | u16 cal_gain; | ||
47 | u16 ncorr[5]; | ||
48 | }; | ||
49 | |||
50 | struct nphy_iq_est { | ||
51 | s32 iq0_prod; | ||
52 | u32 i0_pwr; | ||
53 | u32 q0_pwr; | ||
54 | s32 iq1_prod; | ||
55 | u32 i1_pwr; | ||
56 | u32 q1_pwr; | ||
57 | }; | ||
58 | |||
59 | enum b43_nphy_rf_sequence { | ||
60 | B43_RFSEQ_RX2TX, | ||
61 | B43_RFSEQ_TX2RX, | ||
62 | B43_RFSEQ_RESET2RX, | ||
63 | B43_RFSEQ_UPDATE_GAINH, | ||
64 | B43_RFSEQ_UPDATE_GAINL, | ||
65 | B43_RFSEQ_UPDATE_GAINU, | ||
66 | }; | ||
67 | |||
68 | static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, | ||
69 | u8 *events, u8 *delays, u8 length); | ||
70 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | ||
71 | enum b43_nphy_rf_sequence seq); | ||
72 | static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | ||
73 | u16 value, u8 core, bool off); | ||
74 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | ||
75 | u16 value, u8 core); | ||
32 | 76 | ||
33 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) | 77 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) |
34 | {//TODO | 78 | {//TODO |
@@ -197,173 +241,1020 @@ void b43_nphy_radio_turn_off(struct b43_wldev *dev) | |||
197 | ~B43_NPHY_RFCTL_CMD_EN); | 241 | ~B43_NPHY_RFCTL_CMD_EN); |
198 | } | 242 | } |
199 | 243 | ||
200 | #define ntab_upload(dev, offset, data) do { \ | 244 | /* |
201 | unsigned int i; \ | 245 | * Upload the N-PHY tables. |
202 | for (i = 0; i < (offset##_SIZE); i++) \ | 246 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables |
203 | b43_ntab_write(dev, (offset) + i, (data)[i]); \ | 247 | */ |
204 | } while (0) | ||
205 | |||
206 | /* Upload the N-PHY tables. */ | ||
207 | static void b43_nphy_tables_init(struct b43_wldev *dev) | 248 | static void b43_nphy_tables_init(struct b43_wldev *dev) |
208 | { | 249 | { |
209 | /* Static tables */ | 250 | if (dev->phy.rev < 3) |
210 | ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct); | 251 | b43_nphy_rev0_1_2_tables_init(dev); |
211 | ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup); | 252 | else |
212 | ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap); | 253 | b43_nphy_rev3plus_tables_init(dev); |
213 | ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn); | 254 | } |
214 | ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel); | 255 | |
215 | ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot); | 256 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */ |
216 | ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt); | 257 | static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable) |
217 | ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0); | 258 | { |
218 | ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1); | 259 | struct b43_phy_n *nphy = dev->phy.n; |
219 | ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0); | 260 | enum ieee80211_band band; |
220 | ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1); | 261 | u16 tmp; |
221 | ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi); | 262 | |
222 | ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest); | 263 | if (!enable) { |
223 | ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs); | 264 | nphy->rfctrl_intc1_save = b43_phy_read(dev, |
224 | 265 | B43_NPHY_RFCTL_INTC1); | |
225 | /* Volatile tables */ | 266 | nphy->rfctrl_intc2_save = b43_phy_read(dev, |
226 | ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10); | 267 | B43_NPHY_RFCTL_INTC2); |
227 | ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11); | 268 | band = b43_current_band(dev->wl); |
228 | ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0); | 269 | if (dev->phy.rev >= 3) { |
229 | ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1); | 270 | if (band == IEEE80211_BAND_5GHZ) |
230 | ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0); | 271 | tmp = 0x600; |
231 | ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1); | 272 | else |
232 | ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0); | 273 | tmp = 0x480; |
233 | ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1); | 274 | } else { |
234 | ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0); | 275 | if (band == IEEE80211_BAND_5GHZ) |
235 | ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1); | 276 | tmp = 0x180; |
236 | ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0); | 277 | else |
237 | ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1); | 278 | tmp = 0x120; |
279 | } | ||
280 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp); | ||
281 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp); | ||
282 | } else { | ||
283 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, | ||
284 | nphy->rfctrl_intc1_save); | ||
285 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, | ||
286 | nphy->rfctrl_intc2_save); | ||
287 | } | ||
238 | } | 288 | } |
239 | 289 | ||
240 | static void b43_nphy_workarounds(struct b43_wldev *dev) | 290 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */ |
291 | static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev) | ||
292 | { | ||
293 | struct b43_phy_n *nphy = dev->phy.n; | ||
294 | u16 tmp; | ||
295 | enum ieee80211_band band = b43_current_band(dev->wl); | ||
296 | bool ipa = (nphy->ipa2g_on && band == IEEE80211_BAND_2GHZ) || | ||
297 | (nphy->ipa5g_on && band == IEEE80211_BAND_5GHZ); | ||
298 | |||
299 | if (dev->phy.rev >= 3) { | ||
300 | if (ipa) { | ||
301 | tmp = 4; | ||
302 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2, | ||
303 | (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp); | ||
304 | } | ||
305 | |||
306 | tmp = 1; | ||
307 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2, | ||
308 | (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */ | ||
313 | static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force) | ||
314 | { | ||
315 | u32 tmslow; | ||
316 | |||
317 | if (dev->phy.type != B43_PHYTYPE_N) | ||
318 | return; | ||
319 | |||
320 | tmslow = ssb_read32(dev->dev, SSB_TMSLOW); | ||
321 | if (force) | ||
322 | tmslow |= SSB_TMSLOW_FGC; | ||
323 | else | ||
324 | tmslow &= ~SSB_TMSLOW_FGC; | ||
325 | ssb_write32(dev->dev, SSB_TMSLOW, tmslow); | ||
326 | } | ||
327 | |||
328 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ | ||
329 | static void b43_nphy_reset_cca(struct b43_wldev *dev) | ||
330 | { | ||
331 | u16 bbcfg; | ||
332 | |||
333 | b43_nphy_bmac_clock_fgc(dev, 1); | ||
334 | bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG); | ||
335 | b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA); | ||
336 | udelay(1); | ||
337 | b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); | ||
338 | b43_nphy_bmac_clock_fgc(dev, 0); | ||
339 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | ||
340 | } | ||
341 | |||
342 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */ | ||
343 | static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble) | ||
344 | { | ||
345 | u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG); | ||
346 | |||
347 | mimocfg |= B43_NPHY_MIMOCFG_AUTO; | ||
348 | if (preamble == 1) | ||
349 | mimocfg |= B43_NPHY_MIMOCFG_GFMIX; | ||
350 | else | ||
351 | mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX; | ||
352 | |||
353 | b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg); | ||
354 | } | ||
355 | |||
356 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */ | ||
357 | static void b43_nphy_update_txrx_chain(struct b43_wldev *dev) | ||
358 | { | ||
359 | struct b43_phy_n *nphy = dev->phy.n; | ||
360 | |||
361 | bool override = false; | ||
362 | u16 chain = 0x33; | ||
363 | |||
364 | if (nphy->txrx_chain == 0) { | ||
365 | chain = 0x11; | ||
366 | override = true; | ||
367 | } else if (nphy->txrx_chain == 1) { | ||
368 | chain = 0x22; | ||
369 | override = true; | ||
370 | } | ||
371 | |||
372 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, | ||
373 | ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN), | ||
374 | chain); | ||
375 | |||
376 | if (override) | ||
377 | b43_phy_set(dev, B43_NPHY_RFSEQMODE, | ||
378 | B43_NPHY_RFSEQMODE_CAOVER); | ||
379 | else | ||
380 | b43_phy_mask(dev, B43_NPHY_RFSEQMODE, | ||
381 | ~B43_NPHY_RFSEQMODE_CAOVER); | ||
382 | } | ||
383 | |||
384 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */ | ||
385 | static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est, | ||
386 | u16 samps, u8 time, bool wait) | ||
387 | { | ||
388 | int i; | ||
389 | u16 tmp; | ||
390 | |||
391 | b43_phy_write(dev, B43_NPHY_IQEST_SAMCNT, samps); | ||
392 | b43_phy_maskset(dev, B43_NPHY_IQEST_WT, ~B43_NPHY_IQEST_WT_VAL, time); | ||
393 | if (wait) | ||
394 | b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_MODE); | ||
395 | else | ||
396 | b43_phy_mask(dev, B43_NPHY_IQEST_CMD, ~B43_NPHY_IQEST_CMD_MODE); | ||
397 | |||
398 | b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_START); | ||
399 | |||
400 | for (i = 1000; i; i--) { | ||
401 | tmp = b43_phy_read(dev, B43_NPHY_IQEST_CMD); | ||
402 | if (!(tmp & B43_NPHY_IQEST_CMD_START)) { | ||
403 | est->i0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI0) << 16) | | ||
404 | b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO0); | ||
405 | est->q0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI0) << 16) | | ||
406 | b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO0); | ||
407 | est->iq0_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI0) << 16) | | ||
408 | b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO0); | ||
409 | |||
410 | est->i1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI1) << 16) | | ||
411 | b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO1); | ||
412 | est->q1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI1) << 16) | | ||
413 | b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO1); | ||
414 | est->iq1_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI1) << 16) | | ||
415 | b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO1); | ||
416 | return; | ||
417 | } | ||
418 | udelay(10); | ||
419 | } | ||
420 | memset(est, 0, sizeof(*est)); | ||
421 | } | ||
422 | |||
423 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqCoeffs */ | ||
424 | static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write, | ||
425 | struct b43_phy_n_iq_comp *pcomp) | ||
426 | { | ||
427 | if (write) { | ||
428 | b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPA0, pcomp->a0); | ||
429 | b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPB0, pcomp->b0); | ||
430 | b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPA1, pcomp->a1); | ||
431 | b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPB1, pcomp->b1); | ||
432 | } else { | ||
433 | pcomp->a0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPA0); | ||
434 | pcomp->b0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPB0); | ||
435 | pcomp->a1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPA1); | ||
436 | pcomp->b1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPB1); | ||
437 | } | ||
438 | } | ||
439 | |||
440 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */ | ||
441 | static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core) | ||
442 | { | ||
443 | u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; | ||
444 | |||
445 | b43_phy_write(dev, B43_NPHY_RFSEQCA, regs[0]); | ||
446 | if (core == 0) { | ||
447 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[1]); | ||
448 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]); | ||
449 | } else { | ||
450 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]); | ||
451 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]); | ||
452 | } | ||
453 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[3]); | ||
454 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[4]); | ||
455 | b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, regs[5]); | ||
456 | b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, regs[6]); | ||
457 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, regs[7]); | ||
458 | b43_phy_write(dev, B43_NPHY_RFCTL_OVER, regs[8]); | ||
459 | b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]); | ||
460 | b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]); | ||
461 | } | ||
462 | |||
463 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */ | ||
464 | static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) | ||
465 | { | ||
466 | u8 rxval, txval; | ||
467 | u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; | ||
468 | |||
469 | regs[0] = b43_phy_read(dev, B43_NPHY_RFSEQCA); | ||
470 | if (core == 0) { | ||
471 | regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||
472 | regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); | ||
473 | } else { | ||
474 | regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||
475 | regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
476 | } | ||
477 | regs[3] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | ||
478 | regs[4] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | ||
479 | regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); | ||
480 | regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2); | ||
481 | regs[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S1); | ||
482 | regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER); | ||
483 | regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); | ||
484 | regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); | ||
485 | |||
486 | b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001); | ||
487 | b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001); | ||
488 | |||
489 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, (u16)~B43_NPHY_RFSEQCA_RXDIS, | ||
490 | ((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT)); | ||
491 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN, | ||
492 | ((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT)); | ||
493 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN, | ||
494 | (core << B43_NPHY_RFSEQCA_RXEN_SHIFT)); | ||
495 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXDIS, | ||
496 | (core << B43_NPHY_RFSEQCA_TXDIS_SHIFT)); | ||
497 | |||
498 | if (core == 0) { | ||
499 | b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x0007); | ||
500 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0007); | ||
501 | } else { | ||
502 | b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x0007); | ||
503 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007); | ||
504 | } | ||
505 | |||
506 | b43_nphy_rf_control_intc_override(dev, 2, 0, 3); | ||
507 | b43_nphy_rf_control_override(dev, 8, 0, 3, false); | ||
508 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); | ||
509 | |||
510 | if (core == 0) { | ||
511 | rxval = 1; | ||
512 | txval = 8; | ||
513 | } else { | ||
514 | rxval = 4; | ||
515 | txval = 2; | ||
516 | } | ||
517 | b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1)); | ||
518 | b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core)); | ||
519 | } | ||
520 | |||
521 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ | ||
522 | static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) | ||
523 | { | ||
524 | int i; | ||
525 | s32 iq; | ||
526 | u32 ii; | ||
527 | u32 qq; | ||
528 | int iq_nbits, qq_nbits; | ||
529 | int arsh, brsh; | ||
530 | u16 tmp, a, b; | ||
531 | |||
532 | struct nphy_iq_est est; | ||
533 | struct b43_phy_n_iq_comp old; | ||
534 | struct b43_phy_n_iq_comp new = { }; | ||
535 | bool error = false; | ||
536 | |||
537 | if (mask == 0) | ||
538 | return; | ||
539 | |||
540 | b43_nphy_rx_iq_coeffs(dev, false, &old); | ||
541 | b43_nphy_rx_iq_coeffs(dev, true, &new); | ||
542 | b43_nphy_rx_iq_est(dev, &est, 0x4000, 32, false); | ||
543 | new = old; | ||
544 | |||
545 | for (i = 0; i < 2; i++) { | ||
546 | if (i == 0 && (mask & 1)) { | ||
547 | iq = est.iq0_prod; | ||
548 | ii = est.i0_pwr; | ||
549 | qq = est.q0_pwr; | ||
550 | } else if (i == 1 && (mask & 2)) { | ||
551 | iq = est.iq1_prod; | ||
552 | ii = est.i1_pwr; | ||
553 | qq = est.q1_pwr; | ||
554 | } else { | ||
555 | B43_WARN_ON(1); | ||
556 | continue; | ||
557 | } | ||
558 | |||
559 | if (ii + qq < 2) { | ||
560 | error = true; | ||
561 | break; | ||
562 | } | ||
563 | |||
564 | iq_nbits = fls(abs(iq)); | ||
565 | qq_nbits = fls(qq); | ||
566 | |||
567 | arsh = iq_nbits - 20; | ||
568 | if (arsh >= 0) { | ||
569 | a = -((iq << (30 - iq_nbits)) + (ii >> (1 + arsh))); | ||
570 | tmp = ii >> arsh; | ||
571 | } else { | ||
572 | a = -((iq << (30 - iq_nbits)) + (ii << (-1 - arsh))); | ||
573 | tmp = ii << -arsh; | ||
574 | } | ||
575 | if (tmp == 0) { | ||
576 | error = true; | ||
577 | break; | ||
578 | } | ||
579 | a /= tmp; | ||
580 | |||
581 | brsh = qq_nbits - 11; | ||
582 | if (brsh >= 0) { | ||
583 | b = (qq << (31 - qq_nbits)); | ||
584 | tmp = ii >> brsh; | ||
585 | } else { | ||
586 | b = (qq << (31 - qq_nbits)); | ||
587 | tmp = ii << -brsh; | ||
588 | } | ||
589 | if (tmp == 0) { | ||
590 | error = true; | ||
591 | break; | ||
592 | } | ||
593 | b = int_sqrt(b / tmp - a * a) - (1 << 10); | ||
594 | |||
595 | if (i == 0 && (mask & 0x1)) { | ||
596 | if (dev->phy.rev >= 3) { | ||
597 | new.a0 = a & 0x3FF; | ||
598 | new.b0 = b & 0x3FF; | ||
599 | } else { | ||
600 | new.a0 = b & 0x3FF; | ||
601 | new.b0 = a & 0x3FF; | ||
602 | } | ||
603 | } else if (i == 1 && (mask & 0x2)) { | ||
604 | if (dev->phy.rev >= 3) { | ||
605 | new.a1 = a & 0x3FF; | ||
606 | new.b1 = b & 0x3FF; | ||
607 | } else { | ||
608 | new.a1 = b & 0x3FF; | ||
609 | new.b1 = a & 0x3FF; | ||
610 | } | ||
611 | } | ||
612 | } | ||
613 | |||
614 | if (error) | ||
615 | new = old; | ||
616 | |||
617 | b43_nphy_rx_iq_coeffs(dev, true, &new); | ||
618 | } | ||
619 | |||
620 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxIqWar */ | ||
621 | static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev) | ||
622 | { | ||
623 | u16 array[4]; | ||
624 | int i; | ||
625 | |||
626 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C50); | ||
627 | for (i = 0; i < 4; i++) | ||
628 | array[i] = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); | ||
629 | |||
630 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW0, array[0]); | ||
631 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW1, array[1]); | ||
632 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW2, array[2]); | ||
633 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]); | ||
634 | } | ||
635 | |||
636 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */ | ||
637 | static void b43_nphy_write_clip_detection(struct b43_wldev *dev, u16 *clip_st) | ||
638 | { | ||
639 | b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]); | ||
640 | b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]); | ||
641 | } | ||
642 | |||
643 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */ | ||
644 | static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st) | ||
645 | { | ||
646 | clip_st[0] = b43_phy_read(dev, B43_NPHY_C1_CLIP1THRES); | ||
647 | clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES); | ||
648 | } | ||
649 | |||
650 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ | ||
651 | static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) | ||
652 | { | ||
653 | u16 tmp; | ||
654 | |||
655 | if (dev->dev->id.revision == 16) | ||
656 | b43_mac_suspend(dev); | ||
657 | |||
658 | tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); | ||
659 | tmp &= (B43_NPHY_CLASSCTL_CCKEN | B43_NPHY_CLASSCTL_OFDMEN | | ||
660 | B43_NPHY_CLASSCTL_WAITEDEN); | ||
661 | tmp &= ~mask; | ||
662 | tmp |= (val & mask); | ||
663 | b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); | ||
664 | |||
665 | if (dev->dev->id.revision == 16) | ||
666 | b43_mac_enable(dev); | ||
667 | |||
668 | return tmp; | ||
669 | } | ||
670 | |||
671 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/carriersearch */ | ||
672 | static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable) | ||
241 | { | 673 | { |
242 | struct b43_phy *phy = &dev->phy; | 674 | struct b43_phy *phy = &dev->phy; |
243 | unsigned int i; | 675 | struct b43_phy_n *nphy = phy->n; |
244 | 676 | ||
245 | b43_phy_set(dev, B43_NPHY_IQFLIP, | 677 | if (enable) { |
246 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); | 678 | u16 clip[] = { 0xFFFF, 0xFFFF }; |
247 | if (1 /* FIXME band is 2.4GHz */) { | 679 | if (nphy->deaf_count++ == 0) { |
248 | b43_phy_set(dev, B43_NPHY_CLASSCTL, | 680 | nphy->classifier_state = b43_nphy_classifier(dev, 0, 0); |
249 | B43_NPHY_CLASSCTL_CCKEN); | 681 | b43_nphy_classifier(dev, 0x7, 0); |
250 | } else { | 682 | b43_nphy_read_clip_detection(dev, nphy->clip_state); |
251 | b43_phy_mask(dev, B43_NPHY_CLASSCTL, | 683 | b43_nphy_write_clip_detection(dev, clip); |
252 | ~B43_NPHY_CLASSCTL_CCKEN); | 684 | } |
253 | } | 685 | b43_nphy_reset_cca(dev); |
254 | b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); | 686 | } else { |
255 | b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8); | 687 | if (--nphy->deaf_count == 0) { |
256 | 688 | b43_nphy_classifier(dev, 0x7, nphy->classifier_state); | |
257 | /* Fixup some tables */ | 689 | b43_nphy_write_clip_detection(dev, nphy->clip_state); |
258 | b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA); | 690 | } |
259 | b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA); | 691 | } |
260 | b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); | 692 | } |
261 | b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); | 693 | |
262 | b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0); | 694 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */ |
263 | b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0); | 695 | static void b43_nphy_stop_playback(struct b43_wldev *dev) |
264 | b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); | 696 | { |
265 | b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); | 697 | struct b43_phy_n *nphy = dev->phy.n; |
266 | b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800); | 698 | u16 tmp; |
267 | b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800); | 699 | |
268 | 700 | if (nphy->hang_avoid) | |
269 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | 701 | b43_nphy_stay_in_carrier_search(dev, 1); |
270 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | 702 | |
271 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | 703 | tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT); |
272 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | 704 | if (tmp & 0x1) |
273 | 705 | b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP); | |
274 | //TODO set RF sequence | 706 | else if (tmp & 0x2) |
275 | 707 | b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, (u16)~0x8000); | |
276 | /* Set narrowband clip threshold */ | 708 | |
277 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66); | 709 | b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004); |
278 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66); | 710 | |
279 | 711 | if (nphy->bb_mult_save & 0x80000000) { | |
280 | /* Set wideband clip 2 threshold */ | 712 | tmp = nphy->bb_mult_save & 0xFFFF; |
281 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | 713 | b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); |
282 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, | 714 | nphy->bb_mult_save = 0; |
283 | 21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT); | 715 | } |
284 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | 716 | |
285 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, | 717 | if (nphy->hang_avoid) |
286 | 21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT); | 718 | b43_nphy_stay_in_carrier_search(dev, 0); |
287 | 719 | } | |
288 | /* Set Clip 2 detect */ | 720 | |
289 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | 721 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */ |
290 | B43_NPHY_C1_CGAINI_CL2DETECT); | 722 | static void b43_nphy_spur_workaround(struct b43_wldev *dev) |
291 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | 723 | { |
292 | B43_NPHY_C2_CGAINI_CL2DETECT); | 724 | struct b43_phy_n *nphy = dev->phy.n; |
293 | 725 | ||
294 | if (0 /*FIXME*/) { | 726 | unsigned int channel; |
295 | /* Set dwell lengths */ | 727 | int tone[2] = { 57, 58 }; |
296 | b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43); | 728 | u32 noise[2] = { 0x3FF, 0x3FF }; |
297 | b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43); | 729 | |
298 | b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9); | 730 | B43_WARN_ON(dev->phy.rev < 3); |
299 | b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9); | 731 | |
300 | 732 | if (nphy->hang_avoid) | |
301 | /* Set gain backoff */ | 733 | b43_nphy_stay_in_carrier_search(dev, 1); |
302 | b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, | 734 | |
303 | ~B43_NPHY_C1_CGAINI_GAINBKOFF, | 735 | /* FIXME: channel = radio_chanspec */ |
304 | 1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT); | 736 | |
305 | b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, | 737 | if (nphy->gband_spurwar_en) { |
306 | ~B43_NPHY_C2_CGAINI_GAINBKOFF, | 738 | /* TODO: N PHY Adjust Analog Pfbw (7) */ |
307 | 1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT); | 739 | if (channel == 11 && dev->phy.is_40mhz) |
740 | ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/ | ||
741 | else | ||
742 | ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/ | ||
743 | /* TODO: N PHY Adjust CRS Min Power (0x1E) */ | ||
744 | } | ||
745 | |||
746 | if (nphy->aband_spurwar_en) { | ||
747 | if (channel == 54) { | ||
748 | tone[0] = 0x20; | ||
749 | noise[0] = 0x25F; | ||
750 | } else if (channel == 38 || channel == 102 || channel == 118) { | ||
751 | if (0 /* FIXME */) { | ||
752 | tone[0] = 0x20; | ||
753 | noise[0] = 0x21F; | ||
754 | } else { | ||
755 | tone[0] = 0; | ||
756 | noise[0] = 0; | ||
757 | } | ||
758 | } else if (channel == 134) { | ||
759 | tone[0] = 0x20; | ||
760 | noise[0] = 0x21F; | ||
761 | } else if (channel == 151) { | ||
762 | tone[0] = 0x10; | ||
763 | noise[0] = 0x23F; | ||
764 | } else if (channel == 153 || channel == 161) { | ||
765 | tone[0] = 0x30; | ||
766 | noise[0] = 0x23F; | ||
767 | } else { | ||
768 | tone[0] = 0; | ||
769 | noise[0] = 0; | ||
770 | } | ||
771 | |||
772 | if (!tone[0] && !noise[0]) | ||
773 | ; /* TODO: N PHY Adjust Min Noise Var(1, tone, noise)*/ | ||
774 | else | ||
775 | ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/ | ||
776 | } | ||
777 | |||
778 | if (nphy->hang_avoid) | ||
779 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
780 | } | ||
781 | |||
782 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ | ||
783 | static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) | ||
784 | { | ||
785 | struct b43_phy_n *nphy = dev->phy.n; | ||
786 | u8 i, j; | ||
787 | u8 code; | ||
788 | |||
789 | /* TODO: for PHY >= 3 | ||
790 | s8 *lna1_gain, *lna2_gain; | ||
791 | u8 *gain_db, *gain_bits; | ||
792 | u16 *rfseq_init; | ||
793 | u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; | ||
794 | u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; | ||
795 | */ | ||
796 | |||
797 | u8 rfseq_events[3] = { 6, 8, 7 }; | ||
798 | u8 rfseq_delays[3] = { 10, 30, 1 }; | ||
799 | |||
800 | if (dev->phy.rev >= 3) { | ||
801 | /* TODO */ | ||
802 | } else { | ||
803 | /* Set Clip 2 detect */ | ||
804 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | ||
805 | B43_NPHY_C1_CGAINI_CL2DETECT); | ||
806 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | ||
807 | B43_NPHY_C2_CGAINI_CL2DETECT); | ||
808 | |||
809 | /* Set narrowband clip threshold */ | ||
810 | b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84); | ||
811 | b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84); | ||
812 | |||
813 | if (!dev->phy.is_40mhz) { | ||
814 | /* Set dwell lengths */ | ||
815 | b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B); | ||
816 | b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B); | ||
817 | b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009); | ||
818 | b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009); | ||
819 | } | ||
820 | |||
821 | /* Set wideband clip 2 threshold */ | ||
822 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | ||
823 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, | ||
824 | 21); | ||
825 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | ||
826 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, | ||
827 | 21); | ||
828 | |||
829 | if (!dev->phy.is_40mhz) { | ||
830 | b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, | ||
831 | ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1); | ||
832 | b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, | ||
833 | ~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1); | ||
834 | b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI, | ||
835 | ~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1); | ||
836 | b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI, | ||
837 | ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1); | ||
838 | } | ||
839 | |||
840 | b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); | ||
841 | |||
842 | if (nphy->gain_boost) { | ||
843 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ && | ||
844 | dev->phy.is_40mhz) | ||
845 | code = 4; | ||
846 | else | ||
847 | code = 5; | ||
848 | } else { | ||
849 | code = dev->phy.is_40mhz ? 6 : 7; | ||
850 | } | ||
308 | 851 | ||
309 | /* Set HPVGA2 index */ | 852 | /* Set HPVGA2 index */ |
310 | b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, | 853 | b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, |
311 | ~B43_NPHY_C1_INITGAIN_HPVGA2, | 854 | ~B43_NPHY_C1_INITGAIN_HPVGA2, |
312 | 6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); | 855 | code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); |
313 | b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, | 856 | b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, |
314 | ~B43_NPHY_C2_INITGAIN_HPVGA2, | 857 | ~B43_NPHY_C2_INITGAIN_HPVGA2, |
315 | 6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); | 858 | code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); |
859 | |||
860 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); | ||
861 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
862 | (code << 8 | 0x7C)); | ||
863 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
864 | (code << 8 | 0x7C)); | ||
865 | |||
866 | /* TODO: b43_nphy_adjust_lna_gain_table(dev); */ | ||
867 | |||
868 | if (nphy->elna_gain_config) { | ||
869 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); | ||
870 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); | ||
871 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
872 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
873 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
874 | |||
875 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08); | ||
876 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); | ||
877 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
878 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
879 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
880 | |||
881 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); | ||
882 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
883 | (code << 8 | 0x74)); | ||
884 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
885 | (code << 8 | 0x74)); | ||
886 | } | ||
316 | 887 | ||
317 | //FIXME verify that the specs really mean to use autoinc here. | 888 | if (dev->phy.rev == 2) { |
318 | for (i = 0; i < 3; i++) | 889 | for (i = 0; i < 4; i++) { |
319 | b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673); | 890 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, |
891 | (0x0400 * i) + 0x0020); | ||
892 | for (j = 0; j < 21; j++) | ||
893 | b43_phy_write(dev, | ||
894 | B43_NPHY_TABLE_DATALO, 3 * j); | ||
895 | } | ||
896 | |||
897 | b43_nphy_set_rf_sequence(dev, 5, | ||
898 | rfseq_events, rfseq_delays, 3); | ||
899 | b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, | ||
900 | (u16)~B43_NPHY_OVER_DGAIN_CCKDGECV, | ||
901 | 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); | ||
902 | |||
903 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
904 | b43_phy_maskset(dev, B43_PHY_N(0xC5D), | ||
905 | 0xFF80, 4); | ||
906 | } | ||
320 | } | 907 | } |
908 | } | ||
321 | 909 | ||
322 | /* Set minimum gain value */ | 910 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ |
323 | b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, | 911 | static void b43_nphy_workarounds(struct b43_wldev *dev) |
324 | ~B43_NPHY_C1_MINGAIN, | 912 | { |
325 | 23 << B43_NPHY_C1_MINGAIN_SHIFT); | 913 | struct ssb_bus *bus = dev->dev->bus; |
326 | b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, | 914 | struct b43_phy *phy = &dev->phy; |
327 | ~B43_NPHY_C2_MINGAIN, | 915 | struct b43_phy_n *nphy = phy->n; |
328 | 23 << B43_NPHY_C2_MINGAIN_SHIFT); | ||
329 | 916 | ||
330 | if (phy->rev < 2) { | 917 | u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 }; |
331 | b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, | 918 | u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 }; |
332 | ~B43_NPHY_SCRAM_SIGCTL_SCM); | 919 | |
920 | u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; | ||
921 | u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; | ||
922 | |||
923 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
924 | b43_nphy_classifier(dev, 1, 0); | ||
925 | else | ||
926 | b43_nphy_classifier(dev, 1, 1); | ||
927 | |||
928 | if (nphy->hang_avoid) | ||
929 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
930 | |||
931 | b43_phy_set(dev, B43_NPHY_IQFLIP, | ||
932 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); | ||
933 | |||
934 | if (dev->phy.rev >= 3) { | ||
935 | /* TODO */ | ||
936 | } else { | ||
937 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && | ||
938 | nphy->band5g_pwrgain) { | ||
939 | b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8); | ||
940 | b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8); | ||
941 | } else { | ||
942 | b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); | ||
943 | b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); | ||
944 | } | ||
945 | |||
946 | /* TODO: convert to b43_ntab_write? */ | ||
947 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000); | ||
948 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); | ||
949 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010); | ||
950 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); | ||
951 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002); | ||
952 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA); | ||
953 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012); | ||
954 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA); | ||
955 | |||
956 | if (dev->phy.rev < 2) { | ||
957 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008); | ||
958 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); | ||
959 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018); | ||
960 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); | ||
961 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007); | ||
962 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); | ||
963 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017); | ||
964 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); | ||
965 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006); | ||
966 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800); | ||
967 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016); | ||
968 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800); | ||
969 | } | ||
970 | |||
971 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||
972 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||
973 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||
974 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||
975 | |||
976 | if (bus->sprom.boardflags2_lo & 0x100 && | ||
977 | bus->boardinfo.type == 0x8B) { | ||
978 | delays1[0] = 0x1; | ||
979 | delays1[5] = 0x14; | ||
980 | } | ||
981 | b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); | ||
982 | b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); | ||
983 | |||
984 | b43_nphy_gain_crtl_workarounds(dev); | ||
985 | |||
986 | if (dev->phy.rev < 2) { | ||
987 | if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) | ||
988 | ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/ | ||
989 | } else if (dev->phy.rev == 2) { | ||
990 | b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); | ||
991 | b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); | ||
992 | } | ||
993 | |||
994 | if (dev->phy.rev < 2) | ||
995 | b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, | ||
996 | ~B43_NPHY_SCRAM_SIGCTL_SCM); | ||
997 | |||
998 | /* Set phase track alpha and beta */ | ||
999 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); | ||
1000 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); | ||
1001 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); | ||
1002 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); | ||
1003 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); | ||
1004 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); | ||
1005 | |||
1006 | b43_phy_mask(dev, B43_NPHY_PIL_DW1, | ||
1007 | (u16)~B43_NPHY_PIL_DW_64QAM); | ||
1008 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); | ||
1009 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); | ||
1010 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); | ||
1011 | |||
1012 | if (dev->phy.rev == 2) | ||
1013 | b43_phy_set(dev, B43_NPHY_FINERX2_CGC, | ||
1014 | B43_NPHY_FINERX2_CGC_DECGC); | ||
333 | } | 1015 | } |
334 | 1016 | ||
335 | /* Set phase track alpha and beta */ | 1017 | if (nphy->hang_avoid) |
336 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); | 1018 | b43_nphy_stay_in_carrier_search(dev, 0); |
337 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); | ||
338 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); | ||
339 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); | ||
340 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); | ||
341 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); | ||
342 | } | 1019 | } |
343 | 1020 | ||
344 | static void b43_nphy_reset_cca(struct b43_wldev *dev) | 1021 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */ |
1022 | static int b43_nphy_load_samples(struct b43_wldev *dev, | ||
1023 | struct b43_c32 *samples, u16 len) { | ||
1024 | struct b43_phy_n *nphy = dev->phy.n; | ||
1025 | u16 i; | ||
1026 | u32 *data; | ||
1027 | |||
1028 | data = kzalloc(len * sizeof(u32), GFP_KERNEL); | ||
1029 | if (!data) { | ||
1030 | b43err(dev->wl, "allocation for samples loading failed\n"); | ||
1031 | return -ENOMEM; | ||
1032 | } | ||
1033 | if (nphy->hang_avoid) | ||
1034 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
1035 | |||
1036 | for (i = 0; i < len; i++) { | ||
1037 | data[i] = (samples[i].i & 0x3FF << 10); | ||
1038 | data[i] |= samples[i].q & 0x3FF; | ||
1039 | } | ||
1040 | b43_ntab_write_bulk(dev, B43_NTAB32(17, 0), len, data); | ||
1041 | |||
1042 | kfree(data); | ||
1043 | if (nphy->hang_avoid) | ||
1044 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
1045 | return 0; | ||
1046 | } | ||
1047 | |||
1048 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */ | ||
1049 | static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, | ||
1050 | bool test) | ||
345 | { | 1051 | { |
346 | u16 bbcfg; | 1052 | int i; |
1053 | u16 bw, len, rot, angle; | ||
1054 | struct b43_c32 *samples; | ||
347 | 1055 | ||
348 | ssb_write32(dev->dev, SSB_TMSLOW, | 1056 | |
349 | ssb_read32(dev->dev, SSB_TMSLOW) | SSB_TMSLOW_FGC); | 1057 | bw = (dev->phy.is_40mhz) ? 40 : 20; |
350 | bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG); | 1058 | len = bw << 3; |
351 | b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTCCA); | 1059 | |
352 | b43_phy_write(dev, B43_NPHY_BBCFG, | 1060 | if (test) { |
353 | bbcfg & ~B43_NPHY_BBCFG_RSTCCA); | 1061 | if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX) |
354 | ssb_write32(dev->dev, SSB_TMSLOW, | 1062 | bw = 82; |
355 | ssb_read32(dev->dev, SSB_TMSLOW) & ~SSB_TMSLOW_FGC); | 1063 | else |
1064 | bw = 80; | ||
1065 | |||
1066 | if (dev->phy.is_40mhz) | ||
1067 | bw <<= 1; | ||
1068 | |||
1069 | len = bw << 1; | ||
1070 | } | ||
1071 | |||
1072 | samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL); | ||
1073 | if (!samples) { | ||
1074 | b43err(dev->wl, "allocation for samples generation failed\n"); | ||
1075 | return 0; | ||
1076 | } | ||
1077 | rot = (((freq * 36) / bw) << 16) / 100; | ||
1078 | angle = 0; | ||
1079 | |||
1080 | for (i = 0; i < len; i++) { | ||
1081 | samples[i] = b43_cordic(angle); | ||
1082 | angle += rot; | ||
1083 | samples[i].q = CORDIC_CONVERT(samples[i].q * max); | ||
1084 | samples[i].i = CORDIC_CONVERT(samples[i].i * max); | ||
1085 | } | ||
1086 | |||
1087 | i = b43_nphy_load_samples(dev, samples, len); | ||
1088 | kfree(samples); | ||
1089 | return (i < 0) ? 0 : len; | ||
356 | } | 1090 | } |
357 | 1091 | ||
358 | enum b43_nphy_rf_sequence { | 1092 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ |
359 | B43_RFSEQ_RX2TX, | 1093 | static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, |
360 | B43_RFSEQ_TX2RX, | 1094 | u16 wait, bool iqmode, bool dac_test) |
361 | B43_RFSEQ_RESET2RX, | 1095 | { |
362 | B43_RFSEQ_UPDATE_GAINH, | 1096 | struct b43_phy_n *nphy = dev->phy.n; |
363 | B43_RFSEQ_UPDATE_GAINL, | 1097 | int i; |
364 | B43_RFSEQ_UPDATE_GAINU, | 1098 | u16 seq_mode; |
365 | }; | 1099 | u32 tmp; |
1100 | |||
1101 | if (nphy->hang_avoid) | ||
1102 | b43_nphy_stay_in_carrier_search(dev, true); | ||
1103 | |||
1104 | if ((nphy->bb_mult_save & 0x80000000) == 0) { | ||
1105 | tmp = b43_ntab_read(dev, B43_NTAB16(15, 87)); | ||
1106 | nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000; | ||
1107 | } | ||
1108 | |||
1109 | if (!dev->phy.is_40mhz) | ||
1110 | tmp = 0x6464; | ||
1111 | else | ||
1112 | tmp = 0x4747; | ||
1113 | b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); | ||
1114 | |||
1115 | if (nphy->hang_avoid) | ||
1116 | b43_nphy_stay_in_carrier_search(dev, false); | ||
1117 | |||
1118 | b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1)); | ||
1119 | |||
1120 | if (loops != 0xFFFF) | ||
1121 | b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1)); | ||
1122 | else | ||
1123 | b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops); | ||
1124 | |||
1125 | b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait); | ||
1126 | |||
1127 | seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); | ||
1128 | |||
1129 | b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER); | ||
1130 | if (iqmode) { | ||
1131 | b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); | ||
1132 | b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000); | ||
1133 | } else { | ||
1134 | if (dac_test) | ||
1135 | b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5); | ||
1136 | else | ||
1137 | b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1); | ||
1138 | } | ||
1139 | for (i = 0; i < 100; i++) { | ||
1140 | if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) { | ||
1141 | i = 0; | ||
1142 | break; | ||
1143 | } | ||
1144 | udelay(10); | ||
1145 | } | ||
1146 | if (i) | ||
1147 | b43err(dev->wl, "run samples timeout\n"); | ||
1148 | |||
1149 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); | ||
1150 | } | ||
1151 | |||
1152 | /* | ||
1153 | * Transmits a known value for LO calibration | ||
1154 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone | ||
1155 | */ | ||
1156 | static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val, | ||
1157 | bool iqmode, bool dac_test) | ||
1158 | { | ||
1159 | u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test); | ||
1160 | if (samp == 0) | ||
1161 | return -1; | ||
1162 | b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test); | ||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ | ||
1167 | static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) | ||
1168 | { | ||
1169 | struct b43_phy_n *nphy = dev->phy.n; | ||
1170 | int i, j; | ||
1171 | u32 tmp; | ||
1172 | u32 cur_real, cur_imag, real_part, imag_part; | ||
1173 | |||
1174 | u16 buffer[7]; | ||
1175 | |||
1176 | if (nphy->hang_avoid) | ||
1177 | b43_nphy_stay_in_carrier_search(dev, true); | ||
1178 | |||
1179 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); | ||
1180 | |||
1181 | for (i = 0; i < 2; i++) { | ||
1182 | tmp = ((buffer[i * 2] & 0x3FF) << 10) | | ||
1183 | (buffer[i * 2 + 1] & 0x3FF); | ||
1184 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, | ||
1185 | (((i + 26) << 10) | 320)); | ||
1186 | for (j = 0; j < 128; j++) { | ||
1187 | b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, | ||
1188 | ((tmp >> 16) & 0xFFFF)); | ||
1189 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
1190 | (tmp & 0xFFFF)); | ||
1191 | } | ||
1192 | } | ||
1193 | |||
1194 | for (i = 0; i < 2; i++) { | ||
1195 | tmp = buffer[5 + i]; | ||
1196 | real_part = (tmp >> 8) & 0xFF; | ||
1197 | imag_part = (tmp & 0xFF); | ||
1198 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, | ||
1199 | (((i + 26) << 10) | 448)); | ||
1200 | |||
1201 | if (dev->phy.rev >= 3) { | ||
1202 | cur_real = real_part; | ||
1203 | cur_imag = imag_part; | ||
1204 | tmp = ((cur_real & 0xFF) << 8) | (cur_imag & 0xFF); | ||
1205 | } | ||
1206 | |||
1207 | for (j = 0; j < 128; j++) { | ||
1208 | if (dev->phy.rev < 3) { | ||
1209 | cur_real = (real_part * loscale[j] + 128) >> 8; | ||
1210 | cur_imag = (imag_part * loscale[j] + 128) >> 8; | ||
1211 | tmp = ((cur_real & 0xFF) << 8) | | ||
1212 | (cur_imag & 0xFF); | ||
1213 | } | ||
1214 | b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, | ||
1215 | ((tmp >> 16) & 0xFFFF)); | ||
1216 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
1217 | (tmp & 0xFFFF)); | ||
1218 | } | ||
1219 | } | ||
1220 | |||
1221 | if (dev->phy.rev >= 3) { | ||
1222 | b43_shm_write16(dev, B43_SHM_SHARED, | ||
1223 | B43_SHM_SH_NPHY_TXPWR_INDX0, 0xFFFF); | ||
1224 | b43_shm_write16(dev, B43_SHM_SHARED, | ||
1225 | B43_SHM_SH_NPHY_TXPWR_INDX1, 0xFFFF); | ||
1226 | } | ||
1227 | |||
1228 | if (nphy->hang_avoid) | ||
1229 | b43_nphy_stay_in_carrier_search(dev, false); | ||
1230 | } | ||
1231 | |||
1232 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */ | ||
1233 | static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, | ||
1234 | u8 *events, u8 *delays, u8 length) | ||
1235 | { | ||
1236 | struct b43_phy_n *nphy = dev->phy.n; | ||
1237 | u8 i; | ||
1238 | u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F; | ||
1239 | u16 offset1 = cmd << 4; | ||
1240 | u16 offset2 = offset1 + 0x80; | ||
366 | 1241 | ||
1242 | if (nphy->hang_avoid) | ||
1243 | b43_nphy_stay_in_carrier_search(dev, true); | ||
1244 | |||
1245 | b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events); | ||
1246 | b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays); | ||
1247 | |||
1248 | for (i = length; i < 16; i++) { | ||
1249 | b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end); | ||
1250 | b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1); | ||
1251 | } | ||
1252 | |||
1253 | if (nphy->hang_avoid) | ||
1254 | b43_nphy_stay_in_carrier_search(dev, false); | ||
1255 | } | ||
1256 | |||
1257 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */ | ||
367 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | 1258 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, |
368 | enum b43_nphy_rf_sequence seq) | 1259 | enum b43_nphy_rf_sequence seq) |
369 | { | 1260 | { |
@@ -376,6 +1267,7 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | |||
376 | [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, | 1267 | [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, |
377 | }; | 1268 | }; |
378 | int i; | 1269 | int i; |
1270 | u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); | ||
379 | 1271 | ||
380 | B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); | 1272 | B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); |
381 | 1273 | ||
@@ -389,8 +1281,181 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | |||
389 | } | 1281 | } |
390 | b43err(dev->wl, "RF sequence status timeout\n"); | 1282 | b43err(dev->wl, "RF sequence status timeout\n"); |
391 | ok: | 1283 | ok: |
392 | b43_phy_mask(dev, B43_NPHY_RFSEQMODE, | 1284 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); |
393 | ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER)); | 1285 | } |
1286 | |||
1287 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ | ||
1288 | static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | ||
1289 | u16 value, u8 core, bool off) | ||
1290 | { | ||
1291 | int i; | ||
1292 | u8 index = fls(field); | ||
1293 | u8 addr, en_addr, val_addr; | ||
1294 | /* we expect only one bit set */ | ||
1295 | B43_WARN_ON(field & (~(1 << (index - 1)))); | ||
1296 | |||
1297 | if (dev->phy.rev >= 3) { | ||
1298 | const struct nphy_rf_control_override_rev3 *rf_ctrl; | ||
1299 | for (i = 0; i < 2; i++) { | ||
1300 | if (index == 0 || index == 16) { | ||
1301 | b43err(dev->wl, | ||
1302 | "Unsupported RF Ctrl Override call\n"); | ||
1303 | return; | ||
1304 | } | ||
1305 | |||
1306 | rf_ctrl = &tbl_rf_control_override_rev3[index - 1]; | ||
1307 | en_addr = B43_PHY_N((i == 0) ? | ||
1308 | rf_ctrl->en_addr0 : rf_ctrl->en_addr1); | ||
1309 | val_addr = B43_PHY_N((i == 0) ? | ||
1310 | rf_ctrl->val_addr0 : rf_ctrl->val_addr1); | ||
1311 | |||
1312 | if (off) { | ||
1313 | b43_phy_mask(dev, en_addr, ~(field)); | ||
1314 | b43_phy_mask(dev, val_addr, | ||
1315 | ~(rf_ctrl->val_mask)); | ||
1316 | } else { | ||
1317 | if (core == 0 || ((1 << core) & i) != 0) { | ||
1318 | b43_phy_set(dev, en_addr, field); | ||
1319 | b43_phy_maskset(dev, val_addr, | ||
1320 | ~(rf_ctrl->val_mask), | ||
1321 | (value << rf_ctrl->val_shift)); | ||
1322 | } | ||
1323 | } | ||
1324 | } | ||
1325 | } else { | ||
1326 | const struct nphy_rf_control_override_rev2 *rf_ctrl; | ||
1327 | if (off) { | ||
1328 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field)); | ||
1329 | value = 0; | ||
1330 | } else { | ||
1331 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field); | ||
1332 | } | ||
1333 | |||
1334 | for (i = 0; i < 2; i++) { | ||
1335 | if (index <= 1 || index == 16) { | ||
1336 | b43err(dev->wl, | ||
1337 | "Unsupported RF Ctrl Override call\n"); | ||
1338 | return; | ||
1339 | } | ||
1340 | |||
1341 | if (index == 2 || index == 10 || | ||
1342 | (index >= 13 && index <= 15)) { | ||
1343 | core = 1; | ||
1344 | } | ||
1345 | |||
1346 | rf_ctrl = &tbl_rf_control_override_rev2[index - 2]; | ||
1347 | addr = B43_PHY_N((i == 0) ? | ||
1348 | rf_ctrl->addr0 : rf_ctrl->addr1); | ||
1349 | |||
1350 | if ((core & (1 << i)) != 0) | ||
1351 | b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask), | ||
1352 | (value << rf_ctrl->shift)); | ||
1353 | |||
1354 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); | ||
1355 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
1356 | B43_NPHY_RFCTL_CMD_START); | ||
1357 | udelay(1); | ||
1358 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE); | ||
1359 | } | ||
1360 | } | ||
1361 | } | ||
1362 | |||
1363 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */ | ||
1364 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | ||
1365 | u16 value, u8 core) | ||
1366 | { | ||
1367 | u8 i, j; | ||
1368 | u16 reg, tmp, val; | ||
1369 | |||
1370 | B43_WARN_ON(dev->phy.rev < 3); | ||
1371 | B43_WARN_ON(field > 4); | ||
1372 | |||
1373 | for (i = 0; i < 2; i++) { | ||
1374 | if ((core == 1 && i == 1) || (core == 2 && !i)) | ||
1375 | continue; | ||
1376 | |||
1377 | reg = (i == 0) ? | ||
1378 | B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; | ||
1379 | b43_phy_mask(dev, reg, 0xFBFF); | ||
1380 | |||
1381 | switch (field) { | ||
1382 | case 0: | ||
1383 | b43_phy_write(dev, reg, 0); | ||
1384 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | ||
1385 | break; | ||
1386 | case 1: | ||
1387 | if (!i) { | ||
1388 | b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1, | ||
1389 | 0xFC3F, (value << 6)); | ||
1390 | b43_phy_maskset(dev, B43_NPHY_TXF_40CO_B1S1, | ||
1391 | 0xFFFE, 1); | ||
1392 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
1393 | B43_NPHY_RFCTL_CMD_START); | ||
1394 | for (j = 0; j < 100; j++) { | ||
1395 | if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) { | ||
1396 | j = 0; | ||
1397 | break; | ||
1398 | } | ||
1399 | udelay(10); | ||
1400 | } | ||
1401 | if (j) | ||
1402 | b43err(dev->wl, | ||
1403 | "intc override timeout\n"); | ||
1404 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, | ||
1405 | 0xFFFE); | ||
1406 | } else { | ||
1407 | b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC2, | ||
1408 | 0xFC3F, (value << 6)); | ||
1409 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, | ||
1410 | 0xFFFE, 1); | ||
1411 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
1412 | B43_NPHY_RFCTL_CMD_RXTX); | ||
1413 | for (j = 0; j < 100; j++) { | ||
1414 | if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) { | ||
1415 | j = 0; | ||
1416 | break; | ||
1417 | } | ||
1418 | udelay(10); | ||
1419 | } | ||
1420 | if (j) | ||
1421 | b43err(dev->wl, | ||
1422 | "intc override timeout\n"); | ||
1423 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, | ||
1424 | 0xFFFE); | ||
1425 | } | ||
1426 | break; | ||
1427 | case 2: | ||
1428 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
1429 | tmp = 0x0020; | ||
1430 | val = value << 5; | ||
1431 | } else { | ||
1432 | tmp = 0x0010; | ||
1433 | val = value << 4; | ||
1434 | } | ||
1435 | b43_phy_maskset(dev, reg, ~tmp, val); | ||
1436 | break; | ||
1437 | case 3: | ||
1438 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
1439 | tmp = 0x0001; | ||
1440 | val = value; | ||
1441 | } else { | ||
1442 | tmp = 0x0004; | ||
1443 | val = value << 2; | ||
1444 | } | ||
1445 | b43_phy_maskset(dev, reg, ~tmp, val); | ||
1446 | break; | ||
1447 | case 4: | ||
1448 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
1449 | tmp = 0x0002; | ||
1450 | val = value << 1; | ||
1451 | } else { | ||
1452 | tmp = 0x0008; | ||
1453 | val = value << 3; | ||
1454 | } | ||
1455 | b43_phy_maskset(dev, reg, ~tmp, val); | ||
1456 | break; | ||
1457 | } | ||
1458 | } | ||
394 | } | 1459 | } |
395 | 1460 | ||
396 | static void b43_nphy_bphy_init(struct b43_wldev *dev) | 1461 | static void b43_nphy_bphy_init(struct b43_wldev *dev) |
@@ -411,81 +1476,1680 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev) | |||
411 | b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); | 1476 | b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); |
412 | } | 1477 | } |
413 | 1478 | ||
414 | /* RSSI Calibration */ | 1479 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */ |
415 | static void b43_nphy_rssi_cal(struct b43_wldev *dev, u8 type) | 1480 | static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, |
1481 | s8 offset, u8 core, u8 rail, u8 type) | ||
416 | { | 1482 | { |
417 | //TODO | 1483 | u16 tmp; |
1484 | bool core1or5 = (core == 1) || (core == 5); | ||
1485 | bool core2or5 = (core == 2) || (core == 5); | ||
1486 | |||
1487 | offset = clamp_val(offset, -32, 31); | ||
1488 | tmp = ((scale & 0x3F) << 8) | (offset & 0x3F); | ||
1489 | |||
1490 | if (core1or5 && (rail == 0) && (type == 2)) | ||
1491 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp); | ||
1492 | if (core1or5 && (rail == 1) && (type == 2)) | ||
1493 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp); | ||
1494 | if (core2or5 && (rail == 0) && (type == 2)) | ||
1495 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp); | ||
1496 | if (core2or5 && (rail == 1) && (type == 2)) | ||
1497 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp); | ||
1498 | if (core1or5 && (rail == 0) && (type == 0)) | ||
1499 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp); | ||
1500 | if (core1or5 && (rail == 1) && (type == 0)) | ||
1501 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp); | ||
1502 | if (core2or5 && (rail == 0) && (type == 0)) | ||
1503 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp); | ||
1504 | if (core2or5 && (rail == 1) && (type == 0)) | ||
1505 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp); | ||
1506 | if (core1or5 && (rail == 0) && (type == 1)) | ||
1507 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp); | ||
1508 | if (core1or5 && (rail == 1) && (type == 1)) | ||
1509 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp); | ||
1510 | if (core2or5 && (rail == 0) && (type == 1)) | ||
1511 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp); | ||
1512 | if (core2or5 && (rail == 1) && (type == 1)) | ||
1513 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp); | ||
1514 | if (core1or5 && (rail == 0) && (type == 6)) | ||
1515 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp); | ||
1516 | if (core1or5 && (rail == 1) && (type == 6)) | ||
1517 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp); | ||
1518 | if (core2or5 && (rail == 0) && (type == 6)) | ||
1519 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp); | ||
1520 | if (core2or5 && (rail == 1) && (type == 6)) | ||
1521 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp); | ||
1522 | if (core1or5 && (rail == 0) && (type == 3)) | ||
1523 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp); | ||
1524 | if (core1or5 && (rail == 1) && (type == 3)) | ||
1525 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp); | ||
1526 | if (core2or5 && (rail == 0) && (type == 3)) | ||
1527 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp); | ||
1528 | if (core2or5 && (rail == 1) && (type == 3)) | ||
1529 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp); | ||
1530 | if (core1or5 && (type == 4)) | ||
1531 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp); | ||
1532 | if (core2or5 && (type == 4)) | ||
1533 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp); | ||
1534 | if (core1or5 && (type == 5)) | ||
1535 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp); | ||
1536 | if (core2or5 && (type == 5)) | ||
1537 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); | ||
1538 | } | ||
1539 | |||
1540 | static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
1541 | { | ||
1542 | u16 val; | ||
1543 | |||
1544 | if (type < 3) | ||
1545 | val = 0; | ||
1546 | else if (type == 6) | ||
1547 | val = 1; | ||
1548 | else if (type == 3) | ||
1549 | val = 2; | ||
1550 | else | ||
1551 | val = 3; | ||
1552 | |||
1553 | val = (val << 12) | (val << 14); | ||
1554 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); | ||
1555 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); | ||
1556 | |||
1557 | if (type < 3) { | ||
1558 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, | ||
1559 | (type + 1) << 4); | ||
1560 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, | ||
1561 | (type + 1) << 4); | ||
1562 | } | ||
1563 | |||
1564 | /* TODO use some definitions */ | ||
1565 | if (code == 0) { | ||
1566 | b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0); | ||
1567 | if (type < 3) { | ||
1568 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0); | ||
1569 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0); | ||
1570 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0); | ||
1571 | udelay(20); | ||
1572 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); | ||
1573 | } | ||
1574 | } else { | ||
1575 | b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, | ||
1576 | 0x3000); | ||
1577 | if (type < 3) { | ||
1578 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, | ||
1579 | 0xFEC7, 0x0180); | ||
1580 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, | ||
1581 | 0xEFDC, (code << 1 | 0x1021)); | ||
1582 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1); | ||
1583 | udelay(20); | ||
1584 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); | ||
1585 | } | ||
1586 | } | ||
1587 | } | ||
1588 | |||
1589 | static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
1590 | { | ||
1591 | struct b43_phy_n *nphy = dev->phy.n; | ||
1592 | u8 i; | ||
1593 | u16 reg, val; | ||
1594 | |||
1595 | if (code == 0) { | ||
1596 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF); | ||
1597 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF); | ||
1598 | b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF); | ||
1599 | b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF); | ||
1600 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF); | ||
1601 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF); | ||
1602 | b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3); | ||
1603 | b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3); | ||
1604 | } else { | ||
1605 | for (i = 0; i < 2; i++) { | ||
1606 | if ((code == 1 && i == 1) || (code == 2 && !i)) | ||
1607 | continue; | ||
1608 | |||
1609 | reg = (i == 0) ? | ||
1610 | B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER; | ||
1611 | b43_phy_maskset(dev, reg, 0xFDFF, 0x0200); | ||
1612 | |||
1613 | if (type < 3) { | ||
1614 | reg = (i == 0) ? | ||
1615 | B43_NPHY_AFECTL_C1 : | ||
1616 | B43_NPHY_AFECTL_C2; | ||
1617 | b43_phy_maskset(dev, reg, 0xFCFF, 0); | ||
1618 | |||
1619 | reg = (i == 0) ? | ||
1620 | B43_NPHY_RFCTL_LUT_TRSW_UP1 : | ||
1621 | B43_NPHY_RFCTL_LUT_TRSW_UP2; | ||
1622 | b43_phy_maskset(dev, reg, 0xFFC3, 0); | ||
1623 | |||
1624 | if (type == 0) | ||
1625 | val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8; | ||
1626 | else if (type == 1) | ||
1627 | val = 16; | ||
1628 | else | ||
1629 | val = 32; | ||
1630 | b43_phy_set(dev, reg, val); | ||
1631 | |||
1632 | reg = (i == 0) ? | ||
1633 | B43_NPHY_TXF_40CO_B1S0 : | ||
1634 | B43_NPHY_TXF_40CO_B32S1; | ||
1635 | b43_phy_set(dev, reg, 0x0020); | ||
1636 | } else { | ||
1637 | if (type == 6) | ||
1638 | val = 0x0100; | ||
1639 | else if (type == 3) | ||
1640 | val = 0x0200; | ||
1641 | else | ||
1642 | val = 0x0300; | ||
1643 | |||
1644 | reg = (i == 0) ? | ||
1645 | B43_NPHY_AFECTL_C1 : | ||
1646 | B43_NPHY_AFECTL_C2; | ||
1647 | |||
1648 | b43_phy_maskset(dev, reg, 0xFCFF, val); | ||
1649 | b43_phy_maskset(dev, reg, 0xF3FF, val << 2); | ||
1650 | |||
1651 | if (type != 3 && type != 6) { | ||
1652 | enum ieee80211_band band = | ||
1653 | b43_current_band(dev->wl); | ||
1654 | |||
1655 | if ((nphy->ipa2g_on && | ||
1656 | band == IEEE80211_BAND_2GHZ) || | ||
1657 | (nphy->ipa5g_on && | ||
1658 | band == IEEE80211_BAND_5GHZ)) | ||
1659 | val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE; | ||
1660 | else | ||
1661 | val = 0x11; | ||
1662 | reg = (i == 0) ? 0x2000 : 0x3000; | ||
1663 | reg |= B2055_PADDRV; | ||
1664 | b43_radio_write16(dev, reg, val); | ||
1665 | |||
1666 | reg = (i == 0) ? | ||
1667 | B43_NPHY_AFECTL_OVER1 : | ||
1668 | B43_NPHY_AFECTL_OVER; | ||
1669 | b43_phy_set(dev, reg, 0x0200); | ||
1670 | } | ||
1671 | } | ||
1672 | } | ||
1673 | } | ||
1674 | } | ||
1675 | |||
1676 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ | ||
1677 | static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
1678 | { | ||
1679 | if (dev->phy.rev >= 3) | ||
1680 | b43_nphy_rev3_rssi_select(dev, code, type); | ||
1681 | else | ||
1682 | b43_nphy_rev2_rssi_select(dev, code, type); | ||
1683 | } | ||
1684 | |||
1685 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ | ||
1686 | static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) | ||
1687 | { | ||
1688 | int i; | ||
1689 | for (i = 0; i < 2; i++) { | ||
1690 | if (type == 2) { | ||
1691 | if (i == 0) { | ||
1692 | b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM, | ||
1693 | 0xFC, buf[0]); | ||
1694 | b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5, | ||
1695 | 0xFC, buf[1]); | ||
1696 | } else { | ||
1697 | b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM, | ||
1698 | 0xFC, buf[2 * i]); | ||
1699 | b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5, | ||
1700 | 0xFC, buf[2 * i + 1]); | ||
1701 | } | ||
1702 | } else { | ||
1703 | if (i == 0) | ||
1704 | b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5, | ||
1705 | 0xF3, buf[0] << 2); | ||
1706 | else | ||
1707 | b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5, | ||
1708 | 0xF3, buf[2 * i + 1] << 2); | ||
1709 | } | ||
1710 | } | ||
1711 | } | ||
1712 | |||
1713 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */ | ||
1714 | static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | ||
1715 | u8 nsamp) | ||
1716 | { | ||
1717 | int i; | ||
1718 | int out; | ||
1719 | u16 save_regs_phy[9]; | ||
1720 | u16 s[2]; | ||
1721 | |||
1722 | if (dev->phy.rev >= 3) { | ||
1723 | save_regs_phy[0] = b43_phy_read(dev, | ||
1724 | B43_NPHY_RFCTL_LUT_TRSW_UP1); | ||
1725 | save_regs_phy[1] = b43_phy_read(dev, | ||
1726 | B43_NPHY_RFCTL_LUT_TRSW_UP2); | ||
1727 | save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||
1728 | save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||
1729 | save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); | ||
1730 | save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
1731 | save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); | ||
1732 | save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); | ||
1733 | } | ||
1734 | |||
1735 | b43_nphy_rssi_select(dev, 5, type); | ||
1736 | |||
1737 | if (dev->phy.rev < 2) { | ||
1738 | save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL); | ||
1739 | b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5); | ||
1740 | } | ||
1741 | |||
1742 | for (i = 0; i < 4; i++) | ||
1743 | buf[i] = 0; | ||
1744 | |||
1745 | for (i = 0; i < nsamp; i++) { | ||
1746 | if (dev->phy.rev < 2) { | ||
1747 | s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT); | ||
1748 | s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT); | ||
1749 | } else { | ||
1750 | s[0] = b43_phy_read(dev, B43_NPHY_RSSI1); | ||
1751 | s[1] = b43_phy_read(dev, B43_NPHY_RSSI2); | ||
1752 | } | ||
1753 | |||
1754 | buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2; | ||
1755 | buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2; | ||
1756 | buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2; | ||
1757 | buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2; | ||
1758 | } | ||
1759 | out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 | | ||
1760 | (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF); | ||
1761 | |||
1762 | if (dev->phy.rev < 2) | ||
1763 | b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]); | ||
1764 | |||
1765 | if (dev->phy.rev >= 3) { | ||
1766 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, | ||
1767 | save_regs_phy[0]); | ||
1768 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, | ||
1769 | save_regs_phy[1]); | ||
1770 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]); | ||
1771 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]); | ||
1772 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]); | ||
1773 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); | ||
1774 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); | ||
1775 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]); | ||
1776 | } | ||
1777 | |||
1778 | return out; | ||
1779 | } | ||
1780 | |||
1781 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ | ||
1782 | static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) | ||
1783 | { | ||
1784 | int i, j; | ||
1785 | u8 state[4]; | ||
1786 | u8 code, val; | ||
1787 | u16 class, override; | ||
1788 | u8 regs_save_radio[2]; | ||
1789 | u16 regs_save_phy[2]; | ||
1790 | s8 offset[4]; | ||
1791 | |||
1792 | u16 clip_state[2]; | ||
1793 | u16 clip_off[2] = { 0xFFFF, 0xFFFF }; | ||
1794 | s32 results_min[4] = { }; | ||
1795 | u8 vcm_final[4] = { }; | ||
1796 | s32 results[4][4] = { }; | ||
1797 | s32 miniq[4][2] = { }; | ||
1798 | |||
1799 | if (type == 2) { | ||
1800 | code = 0; | ||
1801 | val = 6; | ||
1802 | } else if (type < 2) { | ||
1803 | code = 25; | ||
1804 | val = 4; | ||
1805 | } else { | ||
1806 | B43_WARN_ON(1); | ||
1807 | return; | ||
1808 | } | ||
1809 | |||
1810 | class = b43_nphy_classifier(dev, 0, 0); | ||
1811 | b43_nphy_classifier(dev, 7, 4); | ||
1812 | b43_nphy_read_clip_detection(dev, clip_state); | ||
1813 | b43_nphy_write_clip_detection(dev, clip_off); | ||
1814 | |||
1815 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
1816 | override = 0x140; | ||
1817 | else | ||
1818 | override = 0x110; | ||
1819 | |||
1820 | regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | ||
1821 | regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX); | ||
1822 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override); | ||
1823 | b43_radio_write16(dev, B2055_C1_PD_RXTX, val); | ||
1824 | |||
1825 | regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | ||
1826 | regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX); | ||
1827 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override); | ||
1828 | b43_radio_write16(dev, B2055_C2_PD_RXTX, val); | ||
1829 | |||
1830 | state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07; | ||
1831 | state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07; | ||
1832 | b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8); | ||
1833 | b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8); | ||
1834 | state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07; | ||
1835 | state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07; | ||
1836 | |||
1837 | b43_nphy_rssi_select(dev, 5, type); | ||
1838 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type); | ||
1839 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type); | ||
1840 | |||
1841 | for (i = 0; i < 4; i++) { | ||
1842 | u8 tmp[4]; | ||
1843 | for (j = 0; j < 4; j++) | ||
1844 | tmp[j] = i; | ||
1845 | if (type != 1) | ||
1846 | b43_nphy_set_rssi_2055_vcm(dev, type, tmp); | ||
1847 | b43_nphy_poll_rssi(dev, type, results[i], 8); | ||
1848 | if (type < 2) | ||
1849 | for (j = 0; j < 2; j++) | ||
1850 | miniq[i][j] = min(results[i][2 * j], | ||
1851 | results[i][2 * j + 1]); | ||
1852 | } | ||
1853 | |||
1854 | for (i = 0; i < 4; i++) { | ||
1855 | s32 mind = 40; | ||
1856 | u8 minvcm = 0; | ||
1857 | s32 minpoll = 249; | ||
1858 | s32 curr; | ||
1859 | for (j = 0; j < 4; j++) { | ||
1860 | if (type == 2) | ||
1861 | curr = abs(results[j][i]); | ||
1862 | else | ||
1863 | curr = abs(miniq[j][i / 2] - code * 8); | ||
1864 | |||
1865 | if (curr < mind) { | ||
1866 | mind = curr; | ||
1867 | minvcm = j; | ||
1868 | } | ||
1869 | |||
1870 | if (results[j][i] < minpoll) | ||
1871 | minpoll = results[j][i]; | ||
1872 | } | ||
1873 | results_min[i] = minpoll; | ||
1874 | vcm_final[i] = minvcm; | ||
1875 | } | ||
1876 | |||
1877 | if (type != 1) | ||
1878 | b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final); | ||
1879 | |||
1880 | for (i = 0; i < 4; i++) { | ||
1881 | offset[i] = (code * 8) - results[vcm_final[i]][i]; | ||
1882 | |||
1883 | if (offset[i] < 0) | ||
1884 | offset[i] = -((abs(offset[i]) + 4) / 8); | ||
1885 | else | ||
1886 | offset[i] = (offset[i] + 4) / 8; | ||
1887 | |||
1888 | if (results_min[i] == 248) | ||
1889 | offset[i] = code - 32; | ||
1890 | |||
1891 | if (i % 2 == 0) | ||
1892 | b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0, | ||
1893 | type); | ||
1894 | else | ||
1895 | b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1, | ||
1896 | type); | ||
1897 | } | ||
1898 | |||
1899 | b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]); | ||
1900 | b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]); | ||
1901 | |||
1902 | switch (state[2]) { | ||
1903 | case 1: | ||
1904 | b43_nphy_rssi_select(dev, 1, 2); | ||
1905 | break; | ||
1906 | case 4: | ||
1907 | b43_nphy_rssi_select(dev, 1, 0); | ||
1908 | break; | ||
1909 | case 2: | ||
1910 | b43_nphy_rssi_select(dev, 1, 1); | ||
1911 | break; | ||
1912 | default: | ||
1913 | b43_nphy_rssi_select(dev, 1, 1); | ||
1914 | break; | ||
1915 | } | ||
1916 | |||
1917 | switch (state[3]) { | ||
1918 | case 1: | ||
1919 | b43_nphy_rssi_select(dev, 2, 2); | ||
1920 | break; | ||
1921 | case 4: | ||
1922 | b43_nphy_rssi_select(dev, 2, 0); | ||
1923 | break; | ||
1924 | default: | ||
1925 | b43_nphy_rssi_select(dev, 2, 1); | ||
1926 | break; | ||
1927 | } | ||
1928 | |||
1929 | b43_nphy_rssi_select(dev, 0, type); | ||
1930 | |||
1931 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]); | ||
1932 | b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]); | ||
1933 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]); | ||
1934 | b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]); | ||
1935 | |||
1936 | b43_nphy_classifier(dev, 7, class); | ||
1937 | b43_nphy_write_clip_detection(dev, clip_state); | ||
1938 | } | ||
1939 | |||
1940 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ | ||
1941 | static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) | ||
1942 | { | ||
1943 | /* TODO */ | ||
1944 | } | ||
1945 | |||
1946 | /* | ||
1947 | * RSSI Calibration | ||
1948 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal | ||
1949 | */ | ||
1950 | static void b43_nphy_rssi_cal(struct b43_wldev *dev) | ||
1951 | { | ||
1952 | if (dev->phy.rev >= 3) { | ||
1953 | b43_nphy_rev3_rssi_cal(dev); | ||
1954 | } else { | ||
1955 | b43_nphy_rev2_rssi_cal(dev, 2); | ||
1956 | b43_nphy_rev2_rssi_cal(dev, 0); | ||
1957 | b43_nphy_rev2_rssi_cal(dev, 1); | ||
1958 | } | ||
418 | } | 1959 | } |
419 | 1960 | ||
1961 | /* | ||
1962 | * Restore RSSI Calibration | ||
1963 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal | ||
1964 | */ | ||
1965 | static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev) | ||
1966 | { | ||
1967 | struct b43_phy_n *nphy = dev->phy.n; | ||
1968 | |||
1969 | u16 *rssical_radio_regs = NULL; | ||
1970 | u16 *rssical_phy_regs = NULL; | ||
1971 | |||
1972 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
1973 | if (!nphy->rssical_chanspec_2G) | ||
1974 | return; | ||
1975 | rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; | ||
1976 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; | ||
1977 | } else { | ||
1978 | if (!nphy->rssical_chanspec_5G) | ||
1979 | return; | ||
1980 | rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; | ||
1981 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; | ||
1982 | } | ||
1983 | |||
1984 | /* TODO use some definitions */ | ||
1985 | b43_radio_maskset(dev, 0x602B, 0xE3, rssical_radio_regs[0]); | ||
1986 | b43_radio_maskset(dev, 0x702B, 0xE3, rssical_radio_regs[1]); | ||
1987 | |||
1988 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, rssical_phy_regs[0]); | ||
1989 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, rssical_phy_regs[1]); | ||
1990 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, rssical_phy_regs[2]); | ||
1991 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, rssical_phy_regs[3]); | ||
1992 | |||
1993 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, rssical_phy_regs[4]); | ||
1994 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, rssical_phy_regs[5]); | ||
1995 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, rssical_phy_regs[6]); | ||
1996 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, rssical_phy_regs[7]); | ||
1997 | |||
1998 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, rssical_phy_regs[8]); | ||
1999 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, rssical_phy_regs[9]); | ||
2000 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, rssical_phy_regs[10]); | ||
2001 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]); | ||
2002 | } | ||
2003 | |||
2004 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ | ||
2005 | static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) | ||
2006 | { | ||
2007 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
2008 | if (dev->phy.rev >= 6) { | ||
2009 | /* TODO If the chip is 47162 | ||
2010 | return txpwrctrl_tx_gain_ipa_rev5 */ | ||
2011 | return txpwrctrl_tx_gain_ipa_rev6; | ||
2012 | } else if (dev->phy.rev >= 5) { | ||
2013 | return txpwrctrl_tx_gain_ipa_rev5; | ||
2014 | } else { | ||
2015 | return txpwrctrl_tx_gain_ipa; | ||
2016 | } | ||
2017 | } else { | ||
2018 | return txpwrctrl_tx_gain_ipa_5g; | ||
2019 | } | ||
2020 | } | ||
2021 | |||
2022 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */ | ||
2023 | static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev) | ||
2024 | { | ||
2025 | struct b43_phy_n *nphy = dev->phy.n; | ||
2026 | u16 *save = nphy->tx_rx_cal_radio_saveregs; | ||
2027 | u16 tmp; | ||
2028 | u8 offset, i; | ||
2029 | |||
2030 | if (dev->phy.rev >= 3) { | ||
2031 | for (i = 0; i < 2; i++) { | ||
2032 | tmp = (i == 0) ? 0x2000 : 0x3000; | ||
2033 | offset = i * 11; | ||
2034 | |||
2035 | save[offset + 0] = b43_radio_read16(dev, B2055_CAL_RVARCTL); | ||
2036 | save[offset + 1] = b43_radio_read16(dev, B2055_CAL_LPOCTL); | ||
2037 | save[offset + 2] = b43_radio_read16(dev, B2055_CAL_TS); | ||
2038 | save[offset + 3] = b43_radio_read16(dev, B2055_CAL_RCCALRTS); | ||
2039 | save[offset + 4] = b43_radio_read16(dev, B2055_CAL_RCALRTS); | ||
2040 | save[offset + 5] = b43_radio_read16(dev, B2055_PADDRV); | ||
2041 | save[offset + 6] = b43_radio_read16(dev, B2055_XOCTL1); | ||
2042 | save[offset + 7] = b43_radio_read16(dev, B2055_XOCTL2); | ||
2043 | save[offset + 8] = b43_radio_read16(dev, B2055_XOREGUL); | ||
2044 | save[offset + 9] = b43_radio_read16(dev, B2055_XOMISC); | ||
2045 | save[offset + 10] = b43_radio_read16(dev, B2055_PLL_LFC1); | ||
2046 | |||
2047 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
2048 | b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x0A); | ||
2049 | b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); | ||
2050 | b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); | ||
2051 | b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); | ||
2052 | b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); | ||
2053 | if (nphy->ipa5g_on) { | ||
2054 | b43_radio_write16(dev, tmp | B2055_PADDRV, 4); | ||
2055 | b43_radio_write16(dev, tmp | B2055_XOCTL1, 1); | ||
2056 | } else { | ||
2057 | b43_radio_write16(dev, tmp | B2055_PADDRV, 0); | ||
2058 | b43_radio_write16(dev, tmp | B2055_XOCTL1, 0x2F); | ||
2059 | } | ||
2060 | b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); | ||
2061 | } else { | ||
2062 | b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x06); | ||
2063 | b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); | ||
2064 | b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); | ||
2065 | b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); | ||
2066 | b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); | ||
2067 | b43_radio_write16(dev, tmp | B2055_XOCTL1, 0); | ||
2068 | if (nphy->ipa2g_on) { | ||
2069 | b43_radio_write16(dev, tmp | B2055_PADDRV, 6); | ||
2070 | b43_radio_write16(dev, tmp | B2055_XOCTL2, | ||
2071 | (dev->phy.rev < 5) ? 0x11 : 0x01); | ||
2072 | } else { | ||
2073 | b43_radio_write16(dev, tmp | B2055_PADDRV, 0); | ||
2074 | b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); | ||
2075 | } | ||
2076 | } | ||
2077 | b43_radio_write16(dev, tmp | B2055_XOREGUL, 0); | ||
2078 | b43_radio_write16(dev, tmp | B2055_XOMISC, 0); | ||
2079 | b43_radio_write16(dev, tmp | B2055_PLL_LFC1, 0); | ||
2080 | } | ||
2081 | } else { | ||
2082 | save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1); | ||
2083 | b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29); | ||
2084 | |||
2085 | save[1] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL2); | ||
2086 | b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL2, 0x54); | ||
2087 | |||
2088 | save[2] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL1); | ||
2089 | b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL1, 0x29); | ||
2090 | |||
2091 | save[3] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL2); | ||
2092 | b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL2, 0x54); | ||
2093 | |||
2094 | save[3] = b43_radio_read16(dev, B2055_C1_PWRDET_RXTX); | ||
2095 | save[4] = b43_radio_read16(dev, B2055_C2_PWRDET_RXTX); | ||
2096 | |||
2097 | if (!(b43_phy_read(dev, B43_NPHY_BANDCTL) & | ||
2098 | B43_NPHY_BANDCTL_5GHZ)) { | ||
2099 | b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x04); | ||
2100 | b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x04); | ||
2101 | } else { | ||
2102 | b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x20); | ||
2103 | b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x20); | ||
2104 | } | ||
2105 | |||
2106 | if (dev->phy.rev < 2) { | ||
2107 | b43_radio_set(dev, B2055_C1_TX_BB_MXGM, 0x20); | ||
2108 | b43_radio_set(dev, B2055_C2_TX_BB_MXGM, 0x20); | ||
2109 | } else { | ||
2110 | b43_radio_mask(dev, B2055_C1_TX_BB_MXGM, ~0x20); | ||
2111 | b43_radio_mask(dev, B2055_C2_TX_BB_MXGM, ~0x20); | ||
2112 | } | ||
2113 | } | ||
2114 | } | ||
2115 | |||
2116 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */ | ||
2117 | static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core, | ||
2118 | struct nphy_txgains target, | ||
2119 | struct nphy_iqcal_params *params) | ||
2120 | { | ||
2121 | int i, j, indx; | ||
2122 | u16 gain; | ||
2123 | |||
2124 | if (dev->phy.rev >= 3) { | ||
2125 | params->txgm = target.txgm[core]; | ||
2126 | params->pga = target.pga[core]; | ||
2127 | params->pad = target.pad[core]; | ||
2128 | params->ipa = target.ipa[core]; | ||
2129 | params->cal_gain = (params->txgm << 12) | (params->pga << 8) | | ||
2130 | (params->pad << 4) | (params->ipa); | ||
2131 | for (j = 0; j < 5; j++) | ||
2132 | params->ncorr[j] = 0x79; | ||
2133 | } else { | ||
2134 | gain = (target.pad[core]) | (target.pga[core] << 4) | | ||
2135 | (target.txgm[core] << 8); | ||
2136 | |||
2137 | indx = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? | ||
2138 | 1 : 0; | ||
2139 | for (i = 0; i < 9; i++) | ||
2140 | if (tbl_iqcal_gainparams[indx][i][0] == gain) | ||
2141 | break; | ||
2142 | i = min(i, 8); | ||
2143 | |||
2144 | params->txgm = tbl_iqcal_gainparams[indx][i][1]; | ||
2145 | params->pga = tbl_iqcal_gainparams[indx][i][2]; | ||
2146 | params->pad = tbl_iqcal_gainparams[indx][i][3]; | ||
2147 | params->cal_gain = (params->txgm << 7) | (params->pga << 4) | | ||
2148 | (params->pad << 2); | ||
2149 | for (j = 0; j < 4; j++) | ||
2150 | params->ncorr[j] = tbl_iqcal_gainparams[indx][i][4 + j]; | ||
2151 | } | ||
2152 | } | ||
2153 | |||
2154 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */ | ||
2155 | static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core) | ||
2156 | { | ||
2157 | struct b43_phy_n *nphy = dev->phy.n; | ||
2158 | int i; | ||
2159 | u16 scale, entry; | ||
2160 | |||
2161 | u16 tmp = nphy->txcal_bbmult; | ||
2162 | if (core == 0) | ||
2163 | tmp >>= 8; | ||
2164 | tmp &= 0xff; | ||
2165 | |||
2166 | for (i = 0; i < 18; i++) { | ||
2167 | scale = (ladder_lo[i].percent * tmp) / 100; | ||
2168 | entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env; | ||
2169 | b43_ntab_write(dev, B43_NTAB16(15, i), entry); | ||
2170 | |||
2171 | scale = (ladder_iq[i].percent * tmp) / 100; | ||
2172 | entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env; | ||
2173 | b43_ntab_write(dev, B43_NTAB16(15, i + 32), entry); | ||
2174 | } | ||
2175 | } | ||
2176 | |||
2177 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */ | ||
2178 | static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev) | ||
2179 | { | ||
2180 | int i; | ||
2181 | for (i = 0; i < 15; i++) | ||
2182 | b43_phy_write(dev, B43_PHY_N(0x2C5 + i), | ||
2183 | tbl_tx_filter_coef_rev4[2][i]); | ||
2184 | } | ||
2185 | |||
2186 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */ | ||
2187 | static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev) | ||
2188 | { | ||
2189 | int i, j; | ||
2190 | /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */ | ||
2191 | u16 offset[] = { 0x186, 0x195, 0x2C5 }; | ||
2192 | |||
2193 | for (i = 0; i < 3; i++) | ||
2194 | for (j = 0; j < 15; j++) | ||
2195 | b43_phy_write(dev, B43_PHY_N(offset[i] + j), | ||
2196 | tbl_tx_filter_coef_rev4[i][j]); | ||
2197 | |||
2198 | if (dev->phy.is_40mhz) { | ||
2199 | for (j = 0; j < 15; j++) | ||
2200 | b43_phy_write(dev, B43_PHY_N(offset[0] + j), | ||
2201 | tbl_tx_filter_coef_rev4[3][j]); | ||
2202 | } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
2203 | for (j = 0; j < 15; j++) | ||
2204 | b43_phy_write(dev, B43_PHY_N(offset[0] + j), | ||
2205 | tbl_tx_filter_coef_rev4[5][j]); | ||
2206 | } | ||
2207 | |||
2208 | if (dev->phy.channel == 14) | ||
2209 | for (j = 0; j < 15; j++) | ||
2210 | b43_phy_write(dev, B43_PHY_N(offset[0] + j), | ||
2211 | tbl_tx_filter_coef_rev4[6][j]); | ||
2212 | } | ||
2213 | |||
2214 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */ | ||
2215 | static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) | ||
2216 | { | ||
2217 | struct b43_phy_n *nphy = dev->phy.n; | ||
2218 | |||
2219 | u16 curr_gain[2]; | ||
2220 | struct nphy_txgains target; | ||
2221 | const u32 *table = NULL; | ||
2222 | |||
2223 | if (nphy->txpwrctrl == 0) { | ||
2224 | int i; | ||
2225 | |||
2226 | if (nphy->hang_avoid) | ||
2227 | b43_nphy_stay_in_carrier_search(dev, true); | ||
2228 | b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, curr_gain); | ||
2229 | if (nphy->hang_avoid) | ||
2230 | b43_nphy_stay_in_carrier_search(dev, false); | ||
2231 | |||
2232 | for (i = 0; i < 2; ++i) { | ||
2233 | if (dev->phy.rev >= 3) { | ||
2234 | target.ipa[i] = curr_gain[i] & 0x000F; | ||
2235 | target.pad[i] = (curr_gain[i] & 0x00F0) >> 4; | ||
2236 | target.pga[i] = (curr_gain[i] & 0x0F00) >> 8; | ||
2237 | target.txgm[i] = (curr_gain[i] & 0x7000) >> 12; | ||
2238 | } else { | ||
2239 | target.ipa[i] = curr_gain[i] & 0x0003; | ||
2240 | target.pad[i] = (curr_gain[i] & 0x000C) >> 2; | ||
2241 | target.pga[i] = (curr_gain[i] & 0x0070) >> 4; | ||
2242 | target.txgm[i] = (curr_gain[i] & 0x0380) >> 7; | ||
2243 | } | ||
2244 | } | ||
2245 | } else { | ||
2246 | int i; | ||
2247 | u16 index[2]; | ||
2248 | index[0] = (b43_phy_read(dev, B43_NPHY_C1_TXPCTL_STAT) & | ||
2249 | B43_NPHY_TXPCTL_STAT_BIDX) >> | ||
2250 | B43_NPHY_TXPCTL_STAT_BIDX_SHIFT; | ||
2251 | index[1] = (b43_phy_read(dev, B43_NPHY_C2_TXPCTL_STAT) & | ||
2252 | B43_NPHY_TXPCTL_STAT_BIDX) >> | ||
2253 | B43_NPHY_TXPCTL_STAT_BIDX_SHIFT; | ||
2254 | |||
2255 | for (i = 0; i < 2; ++i) { | ||
2256 | if (dev->phy.rev >= 3) { | ||
2257 | enum ieee80211_band band = | ||
2258 | b43_current_band(dev->wl); | ||
2259 | |||
2260 | if ((nphy->ipa2g_on && | ||
2261 | band == IEEE80211_BAND_2GHZ) || | ||
2262 | (nphy->ipa5g_on && | ||
2263 | band == IEEE80211_BAND_5GHZ)) { | ||
2264 | table = b43_nphy_get_ipa_gain_table(dev); | ||
2265 | } else { | ||
2266 | if (band == IEEE80211_BAND_5GHZ) { | ||
2267 | if (dev->phy.rev == 3) | ||
2268 | table = b43_ntab_tx_gain_rev3_5ghz; | ||
2269 | else if (dev->phy.rev == 4) | ||
2270 | table = b43_ntab_tx_gain_rev4_5ghz; | ||
2271 | else | ||
2272 | table = b43_ntab_tx_gain_rev5plus_5ghz; | ||
2273 | } else { | ||
2274 | table = b43_ntab_tx_gain_rev3plus_2ghz; | ||
2275 | } | ||
2276 | } | ||
2277 | |||
2278 | target.ipa[i] = (table[index[i]] >> 16) & 0xF; | ||
2279 | target.pad[i] = (table[index[i]] >> 20) & 0xF; | ||
2280 | target.pga[i] = (table[index[i]] >> 24) & 0xF; | ||
2281 | target.txgm[i] = (table[index[i]] >> 28) & 0xF; | ||
2282 | } else { | ||
2283 | table = b43_ntab_tx_gain_rev0_1_2; | ||
2284 | |||
2285 | target.ipa[i] = (table[index[i]] >> 16) & 0x3; | ||
2286 | target.pad[i] = (table[index[i]] >> 18) & 0x3; | ||
2287 | target.pga[i] = (table[index[i]] >> 20) & 0x7; | ||
2288 | target.txgm[i] = (table[index[i]] >> 23) & 0x7; | ||
2289 | } | ||
2290 | } | ||
2291 | } | ||
2292 | |||
2293 | return target; | ||
2294 | } | ||
2295 | |||
2296 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */ | ||
2297 | static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev) | ||
2298 | { | ||
2299 | u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; | ||
2300 | |||
2301 | if (dev->phy.rev >= 3) { | ||
2302 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[0]); | ||
2303 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]); | ||
2304 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]); | ||
2305 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[3]); | ||
2306 | b43_phy_write(dev, B43_NPHY_BBCFG, regs[4]); | ||
2307 | b43_ntab_write(dev, B43_NTAB16(8, 3), regs[5]); | ||
2308 | b43_ntab_write(dev, B43_NTAB16(8, 19), regs[6]); | ||
2309 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[7]); | ||
2310 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[8]); | ||
2311 | b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]); | ||
2312 | b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]); | ||
2313 | b43_nphy_reset_cca(dev); | ||
2314 | } else { | ||
2315 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, regs[0]); | ||
2316 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, regs[1]); | ||
2317 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]); | ||
2318 | b43_ntab_write(dev, B43_NTAB16(8, 2), regs[3]); | ||
2319 | b43_ntab_write(dev, B43_NTAB16(8, 18), regs[4]); | ||
2320 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[5]); | ||
2321 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[6]); | ||
2322 | } | ||
2323 | } | ||
2324 | |||
2325 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */ | ||
2326 | static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) | ||
2327 | { | ||
2328 | u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; | ||
2329 | u16 tmp; | ||
2330 | |||
2331 | regs[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||
2332 | regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||
2333 | if (dev->phy.rev >= 3) { | ||
2334 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0xF0FF, 0x0A00); | ||
2335 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0xF0FF, 0x0A00); | ||
2336 | |||
2337 | tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); | ||
2338 | regs[2] = tmp; | ||
2339 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, tmp | 0x0600); | ||
2340 | |||
2341 | tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
2342 | regs[3] = tmp; | ||
2343 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600); | ||
2344 | |||
2345 | regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG); | ||
2346 | b43_phy_mask(dev, B43_NPHY_BBCFG, (u16)~B43_NPHY_BBCFG_RSTRX); | ||
2347 | |||
2348 | tmp = b43_ntab_read(dev, B43_NTAB16(8, 3)); | ||
2349 | regs[5] = tmp; | ||
2350 | b43_ntab_write(dev, B43_NTAB16(8, 3), 0); | ||
2351 | |||
2352 | tmp = b43_ntab_read(dev, B43_NTAB16(8, 19)); | ||
2353 | regs[6] = tmp; | ||
2354 | b43_ntab_write(dev, B43_NTAB16(8, 19), 0); | ||
2355 | regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | ||
2356 | regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | ||
2357 | |||
2358 | b43_nphy_rf_control_intc_override(dev, 2, 1, 3); | ||
2359 | b43_nphy_rf_control_intc_override(dev, 1, 2, 1); | ||
2360 | b43_nphy_rf_control_intc_override(dev, 1, 8, 2); | ||
2361 | |||
2362 | regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); | ||
2363 | regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); | ||
2364 | b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001); | ||
2365 | b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001); | ||
2366 | } else { | ||
2367 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000); | ||
2368 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000); | ||
2369 | tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
2370 | regs[2] = tmp; | ||
2371 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x3000); | ||
2372 | tmp = b43_ntab_read(dev, B43_NTAB16(8, 2)); | ||
2373 | regs[3] = tmp; | ||
2374 | tmp |= 0x2000; | ||
2375 | b43_ntab_write(dev, B43_NTAB16(8, 2), tmp); | ||
2376 | tmp = b43_ntab_read(dev, B43_NTAB16(8, 18)); | ||
2377 | regs[4] = tmp; | ||
2378 | tmp |= 0x2000; | ||
2379 | b43_ntab_write(dev, B43_NTAB16(8, 18), tmp); | ||
2380 | regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | ||
2381 | regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | ||
2382 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
2383 | tmp = 0x0180; | ||
2384 | else | ||
2385 | tmp = 0x0120; | ||
2386 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp); | ||
2387 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp); | ||
2388 | } | ||
2389 | } | ||
2390 | |||
2391 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */ | ||
2392 | static void b43_nphy_save_cal(struct b43_wldev *dev) | ||
2393 | { | ||
2394 | struct b43_phy_n *nphy = dev->phy.n; | ||
2395 | |||
2396 | struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; | ||
2397 | u16 *txcal_radio_regs = NULL; | ||
2398 | u8 *iqcal_chanspec; | ||
2399 | u16 *table = NULL; | ||
2400 | |||
2401 | if (nphy->hang_avoid) | ||
2402 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
2403 | |||
2404 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
2405 | rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G; | ||
2406 | txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G; | ||
2407 | iqcal_chanspec = &nphy->iqcal_chanspec_2G; | ||
2408 | table = nphy->cal_cache.txcal_coeffs_2G; | ||
2409 | } else { | ||
2410 | rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G; | ||
2411 | txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G; | ||
2412 | iqcal_chanspec = &nphy->iqcal_chanspec_5G; | ||
2413 | table = nphy->cal_cache.txcal_coeffs_5G; | ||
2414 | } | ||
2415 | |||
2416 | b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs); | ||
2417 | /* TODO use some definitions */ | ||
2418 | if (dev->phy.rev >= 3) { | ||
2419 | txcal_radio_regs[0] = b43_radio_read(dev, 0x2021); | ||
2420 | txcal_radio_regs[1] = b43_radio_read(dev, 0x2022); | ||
2421 | txcal_radio_regs[2] = b43_radio_read(dev, 0x3021); | ||
2422 | txcal_radio_regs[3] = b43_radio_read(dev, 0x3022); | ||
2423 | txcal_radio_regs[4] = b43_radio_read(dev, 0x2023); | ||
2424 | txcal_radio_regs[5] = b43_radio_read(dev, 0x2024); | ||
2425 | txcal_radio_regs[6] = b43_radio_read(dev, 0x3023); | ||
2426 | txcal_radio_regs[7] = b43_radio_read(dev, 0x3024); | ||
2427 | } else { | ||
2428 | txcal_radio_regs[0] = b43_radio_read(dev, 0x8B); | ||
2429 | txcal_radio_regs[1] = b43_radio_read(dev, 0xBA); | ||
2430 | txcal_radio_regs[2] = b43_radio_read(dev, 0x8D); | ||
2431 | txcal_radio_regs[3] = b43_radio_read(dev, 0xBC); | ||
2432 | } | ||
2433 | *iqcal_chanspec = nphy->radio_chanspec; | ||
2434 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table); | ||
2435 | |||
2436 | if (nphy->hang_avoid) | ||
2437 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
2438 | } | ||
2439 | |||
2440 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */ | ||
2441 | static void b43_nphy_restore_cal(struct b43_wldev *dev) | ||
2442 | { | ||
2443 | struct b43_phy_n *nphy = dev->phy.n; | ||
2444 | |||
2445 | u16 coef[4]; | ||
2446 | u16 *loft = NULL; | ||
2447 | u16 *table = NULL; | ||
2448 | |||
2449 | int i; | ||
2450 | u16 *txcal_radio_regs = NULL; | ||
2451 | struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; | ||
2452 | |||
2453 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
2454 | if (nphy->iqcal_chanspec_2G == 0) | ||
2455 | return; | ||
2456 | table = nphy->cal_cache.txcal_coeffs_2G; | ||
2457 | loft = &nphy->cal_cache.txcal_coeffs_2G[5]; | ||
2458 | } else { | ||
2459 | if (nphy->iqcal_chanspec_5G == 0) | ||
2460 | return; | ||
2461 | table = nphy->cal_cache.txcal_coeffs_5G; | ||
2462 | loft = &nphy->cal_cache.txcal_coeffs_5G[5]; | ||
2463 | } | ||
2464 | |||
2465 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4, table); | ||
2466 | |||
2467 | for (i = 0; i < 4; i++) { | ||
2468 | if (dev->phy.rev >= 3) | ||
2469 | table[i] = coef[i]; | ||
2470 | else | ||
2471 | coef[i] = 0; | ||
2472 | } | ||
2473 | |||
2474 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, coef); | ||
2475 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, loft); | ||
2476 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, loft); | ||
2477 | |||
2478 | if (dev->phy.rev < 2) | ||
2479 | b43_nphy_tx_iq_workaround(dev); | ||
2480 | |||
2481 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
2482 | txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G; | ||
2483 | rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G; | ||
2484 | } else { | ||
2485 | txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G; | ||
2486 | rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G; | ||
2487 | } | ||
2488 | |||
2489 | /* TODO use some definitions */ | ||
2490 | if (dev->phy.rev >= 3) { | ||
2491 | b43_radio_write(dev, 0x2021, txcal_radio_regs[0]); | ||
2492 | b43_radio_write(dev, 0x2022, txcal_radio_regs[1]); | ||
2493 | b43_radio_write(dev, 0x3021, txcal_radio_regs[2]); | ||
2494 | b43_radio_write(dev, 0x3022, txcal_radio_regs[3]); | ||
2495 | b43_radio_write(dev, 0x2023, txcal_radio_regs[4]); | ||
2496 | b43_radio_write(dev, 0x2024, txcal_radio_regs[5]); | ||
2497 | b43_radio_write(dev, 0x3023, txcal_radio_regs[6]); | ||
2498 | b43_radio_write(dev, 0x3024, txcal_radio_regs[7]); | ||
2499 | } else { | ||
2500 | b43_radio_write(dev, 0x8B, txcal_radio_regs[0]); | ||
2501 | b43_radio_write(dev, 0xBA, txcal_radio_regs[1]); | ||
2502 | b43_radio_write(dev, 0x8D, txcal_radio_regs[2]); | ||
2503 | b43_radio_write(dev, 0xBC, txcal_radio_regs[3]); | ||
2504 | } | ||
2505 | b43_nphy_rx_iq_coeffs(dev, true, rxcal_coeffs); | ||
2506 | } | ||
2507 | |||
2508 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalTxIqlo */ | ||
2509 | static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | ||
2510 | struct nphy_txgains target, | ||
2511 | bool full, bool mphase) | ||
2512 | { | ||
2513 | struct b43_phy_n *nphy = dev->phy.n; | ||
2514 | int i; | ||
2515 | int error = 0; | ||
2516 | int freq; | ||
2517 | bool avoid = false; | ||
2518 | u8 length; | ||
2519 | u16 tmp, core, type, count, max, numb, last, cmd; | ||
2520 | const u16 *table; | ||
2521 | bool phy6or5x; | ||
2522 | |||
2523 | u16 buffer[11]; | ||
2524 | u16 diq_start = 0; | ||
2525 | u16 save[2]; | ||
2526 | u16 gain[2]; | ||
2527 | struct nphy_iqcal_params params[2]; | ||
2528 | bool updated[2] = { }; | ||
2529 | |||
2530 | b43_nphy_stay_in_carrier_search(dev, true); | ||
2531 | |||
2532 | if (dev->phy.rev >= 4) { | ||
2533 | avoid = nphy->hang_avoid; | ||
2534 | nphy->hang_avoid = 0; | ||
2535 | } | ||
2536 | |||
2537 | b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, save); | ||
2538 | |||
2539 | for (i = 0; i < 2; i++) { | ||
2540 | b43_nphy_iq_cal_gain_params(dev, i, target, ¶ms[i]); | ||
2541 | gain[i] = params[i].cal_gain; | ||
2542 | } | ||
2543 | |||
2544 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain); | ||
2545 | |||
2546 | b43_nphy_tx_cal_radio_setup(dev); | ||
2547 | b43_nphy_tx_cal_phy_setup(dev); | ||
2548 | |||
2549 | phy6or5x = dev->phy.rev >= 6 || | ||
2550 | (dev->phy.rev == 5 && nphy->ipa2g_on && | ||
2551 | b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ); | ||
2552 | if (phy6or5x) { | ||
2553 | if (dev->phy.is_40mhz) { | ||
2554 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18, | ||
2555 | tbl_tx_iqlo_cal_loft_ladder_40); | ||
2556 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18, | ||
2557 | tbl_tx_iqlo_cal_iqimb_ladder_40); | ||
2558 | } else { | ||
2559 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18, | ||
2560 | tbl_tx_iqlo_cal_loft_ladder_20); | ||
2561 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18, | ||
2562 | tbl_tx_iqlo_cal_iqimb_ladder_20); | ||
2563 | } | ||
2564 | } | ||
2565 | |||
2566 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9); | ||
2567 | |||
2568 | if (!dev->phy.is_40mhz) | ||
2569 | freq = 2500; | ||
2570 | else | ||
2571 | freq = 5000; | ||
2572 | |||
2573 | if (nphy->mphase_cal_phase_id > 2) | ||
2574 | b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8, | ||
2575 | 0xFFFF, 0, true, false); | ||
2576 | else | ||
2577 | error = b43_nphy_tx_tone(dev, freq, 250, true, false); | ||
2578 | |||
2579 | if (error == 0) { | ||
2580 | if (nphy->mphase_cal_phase_id > 2) { | ||
2581 | table = nphy->mphase_txcal_bestcoeffs; | ||
2582 | length = 11; | ||
2583 | if (dev->phy.rev < 3) | ||
2584 | length -= 2; | ||
2585 | } else { | ||
2586 | if (!full && nphy->txiqlocal_coeffsvalid) { | ||
2587 | table = nphy->txiqlocal_bestc; | ||
2588 | length = 11; | ||
2589 | if (dev->phy.rev < 3) | ||
2590 | length -= 2; | ||
2591 | } else { | ||
2592 | full = true; | ||
2593 | if (dev->phy.rev >= 3) { | ||
2594 | table = tbl_tx_iqlo_cal_startcoefs_nphyrev3; | ||
2595 | length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3; | ||
2596 | } else { | ||
2597 | table = tbl_tx_iqlo_cal_startcoefs; | ||
2598 | length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS; | ||
2599 | } | ||
2600 | } | ||
2601 | } | ||
2602 | |||
2603 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, table); | ||
2604 | |||
2605 | if (full) { | ||
2606 | if (dev->phy.rev >= 3) | ||
2607 | max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3; | ||
2608 | else | ||
2609 | max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL; | ||
2610 | } else { | ||
2611 | if (dev->phy.rev >= 3) | ||
2612 | max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3; | ||
2613 | else | ||
2614 | max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL; | ||
2615 | } | ||
2616 | |||
2617 | if (mphase) { | ||
2618 | count = nphy->mphase_txcal_cmdidx; | ||
2619 | numb = min(max, | ||
2620 | (u16)(count + nphy->mphase_txcal_numcmds)); | ||
2621 | } else { | ||
2622 | count = 0; | ||
2623 | numb = max; | ||
2624 | } | ||
2625 | |||
2626 | for (; count < numb; count++) { | ||
2627 | if (full) { | ||
2628 | if (dev->phy.rev >= 3) | ||
2629 | cmd = tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[count]; | ||
2630 | else | ||
2631 | cmd = tbl_tx_iqlo_cal_cmds_fullcal[count]; | ||
2632 | } else { | ||
2633 | if (dev->phy.rev >= 3) | ||
2634 | cmd = tbl_tx_iqlo_cal_cmds_recal_nphyrev3[count]; | ||
2635 | else | ||
2636 | cmd = tbl_tx_iqlo_cal_cmds_recal[count]; | ||
2637 | } | ||
2638 | |||
2639 | core = (cmd & 0x3000) >> 12; | ||
2640 | type = (cmd & 0x0F00) >> 8; | ||
2641 | |||
2642 | if (phy6or5x && updated[core] == 0) { | ||
2643 | b43_nphy_update_tx_cal_ladder(dev, core); | ||
2644 | updated[core] = 1; | ||
2645 | } | ||
2646 | |||
2647 | tmp = (params[core].ncorr[type] << 8) | 0x66; | ||
2648 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp); | ||
2649 | |||
2650 | if (type == 1 || type == 3 || type == 4) { | ||
2651 | buffer[0] = b43_ntab_read(dev, | ||
2652 | B43_NTAB16(15, 69 + core)); | ||
2653 | diq_start = buffer[0]; | ||
2654 | buffer[0] = 0; | ||
2655 | b43_ntab_write(dev, B43_NTAB16(15, 69 + core), | ||
2656 | 0); | ||
2657 | } | ||
2658 | |||
2659 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd); | ||
2660 | for (i = 0; i < 2000; i++) { | ||
2661 | tmp = b43_phy_read(dev, B43_NPHY_IQLOCAL_CMD); | ||
2662 | if (tmp & 0xC000) | ||
2663 | break; | ||
2664 | udelay(10); | ||
2665 | } | ||
2666 | |||
2667 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, | ||
2668 | buffer); | ||
2669 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, | ||
2670 | buffer); | ||
2671 | |||
2672 | if (type == 1 || type == 3 || type == 4) | ||
2673 | buffer[0] = diq_start; | ||
2674 | } | ||
2675 | |||
2676 | if (mphase) | ||
2677 | nphy->mphase_txcal_cmdidx = (numb >= max) ? 0 : numb; | ||
2678 | |||
2679 | last = (dev->phy.rev < 3) ? 6 : 7; | ||
2680 | |||
2681 | if (!mphase || nphy->mphase_cal_phase_id == last) { | ||
2682 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 96), 4, buffer); | ||
2683 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 4, buffer); | ||
2684 | if (dev->phy.rev < 3) { | ||
2685 | buffer[0] = 0; | ||
2686 | buffer[1] = 0; | ||
2687 | buffer[2] = 0; | ||
2688 | buffer[3] = 0; | ||
2689 | } | ||
2690 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, | ||
2691 | buffer); | ||
2692 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2, | ||
2693 | buffer); | ||
2694 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, | ||
2695 | buffer); | ||
2696 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, | ||
2697 | buffer); | ||
2698 | length = 11; | ||
2699 | if (dev->phy.rev < 3) | ||
2700 | length -= 2; | ||
2701 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, | ||
2702 | nphy->txiqlocal_bestc); | ||
2703 | nphy->txiqlocal_coeffsvalid = true; | ||
2704 | /* TODO: Set nphy->txiqlocal_chanspec to | ||
2705 | the current channel */ | ||
2706 | } else { | ||
2707 | length = 11; | ||
2708 | if (dev->phy.rev < 3) | ||
2709 | length -= 2; | ||
2710 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, | ||
2711 | nphy->mphase_txcal_bestcoeffs); | ||
2712 | } | ||
2713 | |||
2714 | b43_nphy_stop_playback(dev); | ||
2715 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0); | ||
2716 | } | ||
2717 | |||
2718 | b43_nphy_tx_cal_phy_cleanup(dev); | ||
2719 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, save); | ||
2720 | |||
2721 | if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last)) | ||
2722 | b43_nphy_tx_iq_workaround(dev); | ||
2723 | |||
2724 | if (dev->phy.rev >= 4) | ||
2725 | nphy->hang_avoid = avoid; | ||
2726 | |||
2727 | b43_nphy_stay_in_carrier_search(dev, false); | ||
2728 | |||
2729 | return error; | ||
2730 | } | ||
2731 | |||
2732 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ReapplyTxCalCoeffs */ | ||
2733 | static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev) | ||
2734 | { | ||
2735 | struct b43_phy_n *nphy = dev->phy.n; | ||
2736 | u8 i; | ||
2737 | u16 buffer[7]; | ||
2738 | bool equal = true; | ||
2739 | |||
2740 | if (!nphy->txiqlocal_coeffsvalid || 1 /* FIXME */) | ||
2741 | return; | ||
2742 | |||
2743 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); | ||
2744 | for (i = 0; i < 4; i++) { | ||
2745 | if (buffer[i] != nphy->txiqlocal_bestc[i]) { | ||
2746 | equal = false; | ||
2747 | break; | ||
2748 | } | ||
2749 | } | ||
2750 | |||
2751 | if (!equal) { | ||
2752 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4, | ||
2753 | nphy->txiqlocal_bestc); | ||
2754 | for (i = 0; i < 4; i++) | ||
2755 | buffer[i] = 0; | ||
2756 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, | ||
2757 | buffer); | ||
2758 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, | ||
2759 | &nphy->txiqlocal_bestc[5]); | ||
2760 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, | ||
2761 | &nphy->txiqlocal_bestc[5]); | ||
2762 | } | ||
2763 | } | ||
2764 | |||
2765 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */ | ||
2766 | static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | ||
2767 | struct nphy_txgains target, u8 type, bool debug) | ||
2768 | { | ||
2769 | struct b43_phy_n *nphy = dev->phy.n; | ||
2770 | int i, j, index; | ||
2771 | u8 rfctl[2]; | ||
2772 | u8 afectl_core; | ||
2773 | u16 tmp[6]; | ||
2774 | u16 cur_hpf1, cur_hpf2, cur_lna; | ||
2775 | u32 real, imag; | ||
2776 | enum ieee80211_band band; | ||
2777 | |||
2778 | u8 use; | ||
2779 | u16 cur_hpf; | ||
2780 | u16 lna[3] = { 3, 3, 1 }; | ||
2781 | u16 hpf1[3] = { 7, 2, 0 }; | ||
2782 | u16 hpf2[3] = { 2, 0, 0 }; | ||
2783 | u32 power[3] = { }; | ||
2784 | u16 gain_save[2]; | ||
2785 | u16 cal_gain[2]; | ||
2786 | struct nphy_iqcal_params cal_params[2]; | ||
2787 | struct nphy_iq_est est; | ||
2788 | int ret = 0; | ||
2789 | bool playtone = true; | ||
2790 | int desired = 13; | ||
2791 | |||
2792 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
2793 | |||
2794 | if (dev->phy.rev < 2) | ||
2795 | b43_nphy_reapply_tx_cal_coeffs(dev); | ||
2796 | b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); | ||
2797 | for (i = 0; i < 2; i++) { | ||
2798 | b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]); | ||
2799 | cal_gain[i] = cal_params[i].cal_gain; | ||
2800 | } | ||
2801 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, cal_gain); | ||
2802 | |||
2803 | for (i = 0; i < 2; i++) { | ||
2804 | if (i == 0) { | ||
2805 | rfctl[0] = B43_NPHY_RFCTL_INTC1; | ||
2806 | rfctl[1] = B43_NPHY_RFCTL_INTC2; | ||
2807 | afectl_core = B43_NPHY_AFECTL_C1; | ||
2808 | } else { | ||
2809 | rfctl[0] = B43_NPHY_RFCTL_INTC2; | ||
2810 | rfctl[1] = B43_NPHY_RFCTL_INTC1; | ||
2811 | afectl_core = B43_NPHY_AFECTL_C2; | ||
2812 | } | ||
2813 | |||
2814 | tmp[1] = b43_phy_read(dev, B43_NPHY_RFSEQCA); | ||
2815 | tmp[2] = b43_phy_read(dev, afectl_core); | ||
2816 | tmp[3] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
2817 | tmp[4] = b43_phy_read(dev, rfctl[0]); | ||
2818 | tmp[5] = b43_phy_read(dev, rfctl[1]); | ||
2819 | |||
2820 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, | ||
2821 | (u16)~B43_NPHY_RFSEQCA_RXDIS, | ||
2822 | ((1 - i) << B43_NPHY_RFSEQCA_RXDIS_SHIFT)); | ||
2823 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN, | ||
2824 | (1 - i)); | ||
2825 | b43_phy_set(dev, afectl_core, 0x0006); | ||
2826 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0006); | ||
2827 | |||
2828 | band = b43_current_band(dev->wl); | ||
2829 | |||
2830 | if (nphy->rxcalparams & 0xFF000000) { | ||
2831 | if (band == IEEE80211_BAND_5GHZ) | ||
2832 | b43_phy_write(dev, rfctl[0], 0x140); | ||
2833 | else | ||
2834 | b43_phy_write(dev, rfctl[0], 0x110); | ||
2835 | } else { | ||
2836 | if (band == IEEE80211_BAND_5GHZ) | ||
2837 | b43_phy_write(dev, rfctl[0], 0x180); | ||
2838 | else | ||
2839 | b43_phy_write(dev, rfctl[0], 0x120); | ||
2840 | } | ||
2841 | |||
2842 | if (band == IEEE80211_BAND_5GHZ) | ||
2843 | b43_phy_write(dev, rfctl[1], 0x148); | ||
2844 | else | ||
2845 | b43_phy_write(dev, rfctl[1], 0x114); | ||
2846 | |||
2847 | if (nphy->rxcalparams & 0x10000) { | ||
2848 | b43_radio_maskset(dev, B2055_C1_GENSPARE2, 0xFC, | ||
2849 | (i + 1)); | ||
2850 | b43_radio_maskset(dev, B2055_C2_GENSPARE2, 0xFC, | ||
2851 | (2 - i)); | ||
2852 | } | ||
2853 | |||
2854 | for (j = 0; i < 4; j++) { | ||
2855 | if (j < 3) { | ||
2856 | cur_lna = lna[j]; | ||
2857 | cur_hpf1 = hpf1[j]; | ||
2858 | cur_hpf2 = hpf2[j]; | ||
2859 | } else { | ||
2860 | if (power[1] > 10000) { | ||
2861 | use = 1; | ||
2862 | cur_hpf = cur_hpf1; | ||
2863 | index = 2; | ||
2864 | } else { | ||
2865 | if (power[0] > 10000) { | ||
2866 | use = 1; | ||
2867 | cur_hpf = cur_hpf1; | ||
2868 | index = 1; | ||
2869 | } else { | ||
2870 | index = 0; | ||
2871 | use = 2; | ||
2872 | cur_hpf = cur_hpf2; | ||
2873 | } | ||
2874 | } | ||
2875 | cur_lna = lna[index]; | ||
2876 | cur_hpf1 = hpf1[index]; | ||
2877 | cur_hpf2 = hpf2[index]; | ||
2878 | cur_hpf += desired - hweight32(power[index]); | ||
2879 | cur_hpf = clamp_val(cur_hpf, 0, 10); | ||
2880 | if (use == 1) | ||
2881 | cur_hpf1 = cur_hpf; | ||
2882 | else | ||
2883 | cur_hpf2 = cur_hpf; | ||
2884 | } | ||
2885 | |||
2886 | tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | | ||
2887 | (cur_lna << 2)); | ||
2888 | b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3, | ||
2889 | false); | ||
2890 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | ||
2891 | b43_nphy_stop_playback(dev); | ||
2892 | |||
2893 | if (playtone) { | ||
2894 | ret = b43_nphy_tx_tone(dev, 4000, | ||
2895 | (nphy->rxcalparams & 0xFFFF), | ||
2896 | false, false); | ||
2897 | playtone = false; | ||
2898 | } else { | ||
2899 | b43_nphy_run_samples(dev, 160, 0xFFFF, 0, | ||
2900 | false, false); | ||
2901 | } | ||
2902 | |||
2903 | if (ret == 0) { | ||
2904 | if (j < 3) { | ||
2905 | b43_nphy_rx_iq_est(dev, &est, 1024, 32, | ||
2906 | false); | ||
2907 | if (i == 0) { | ||
2908 | real = est.i0_pwr; | ||
2909 | imag = est.q0_pwr; | ||
2910 | } else { | ||
2911 | real = est.i1_pwr; | ||
2912 | imag = est.q1_pwr; | ||
2913 | } | ||
2914 | power[i] = ((real + imag) / 1024) + 1; | ||
2915 | } else { | ||
2916 | b43_nphy_calc_rx_iq_comp(dev, 1 << i); | ||
2917 | } | ||
2918 | b43_nphy_stop_playback(dev); | ||
2919 | } | ||
2920 | |||
2921 | if (ret != 0) | ||
2922 | break; | ||
2923 | } | ||
2924 | |||
2925 | b43_radio_mask(dev, B2055_C1_GENSPARE2, 0xFC); | ||
2926 | b43_radio_mask(dev, B2055_C2_GENSPARE2, 0xFC); | ||
2927 | b43_phy_write(dev, rfctl[1], tmp[5]); | ||
2928 | b43_phy_write(dev, rfctl[0], tmp[4]); | ||
2929 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp[3]); | ||
2930 | b43_phy_write(dev, afectl_core, tmp[2]); | ||
2931 | b43_phy_write(dev, B43_NPHY_RFSEQCA, tmp[1]); | ||
2932 | |||
2933 | if (ret != 0) | ||
2934 | break; | ||
2935 | } | ||
2936 | |||
2937 | b43_nphy_rf_control_override(dev, 0x400, 0, 3, true); | ||
2938 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | ||
2939 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); | ||
2940 | |||
2941 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
2942 | |||
2943 | return ret; | ||
2944 | } | ||
2945 | |||
2946 | static int b43_nphy_rev3_cal_rx_iq(struct b43_wldev *dev, | ||
2947 | struct nphy_txgains target, u8 type, bool debug) | ||
2948 | { | ||
2949 | return -1; | ||
2950 | } | ||
2951 | |||
2952 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIq */ | ||
2953 | static int b43_nphy_cal_rx_iq(struct b43_wldev *dev, | ||
2954 | struct nphy_txgains target, u8 type, bool debug) | ||
2955 | { | ||
2956 | if (dev->phy.rev >= 3) | ||
2957 | return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug); | ||
2958 | else | ||
2959 | return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug); | ||
2960 | } | ||
2961 | |||
2962 | /* | ||
2963 | * Init N-PHY | ||
2964 | * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N | ||
2965 | */ | ||
420 | int b43_phy_initn(struct b43_wldev *dev) | 2966 | int b43_phy_initn(struct b43_wldev *dev) |
421 | { | 2967 | { |
2968 | struct ssb_bus *bus = dev->dev->bus; | ||
422 | struct b43_phy *phy = &dev->phy; | 2969 | struct b43_phy *phy = &dev->phy; |
2970 | struct b43_phy_n *nphy = phy->n; | ||
2971 | u8 tx_pwr_state; | ||
2972 | struct nphy_txgains target; | ||
423 | u16 tmp; | 2973 | u16 tmp; |
2974 | enum ieee80211_band tmp2; | ||
2975 | bool do_rssi_cal; | ||
424 | 2976 | ||
425 | //TODO: Spectral management | 2977 | u16 clip[2]; |
2978 | bool do_cal = false; | ||
2979 | |||
2980 | if ((dev->phy.rev >= 3) && | ||
2981 | (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && | ||
2982 | (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { | ||
2983 | chipco_set32(&dev->dev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); | ||
2984 | } | ||
2985 | nphy->deaf_count = 0; | ||
426 | b43_nphy_tables_init(dev); | 2986 | b43_nphy_tables_init(dev); |
2987 | nphy->crsminpwr_adjusted = false; | ||
2988 | nphy->noisevars_adjusted = false; | ||
427 | 2989 | ||
428 | /* Clear all overrides */ | 2990 | /* Clear all overrides */ |
429 | b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0); | 2991 | if (dev->phy.rev >= 3) { |
2992 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0); | ||
2993 | b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0); | ||
2994 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0); | ||
2995 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0); | ||
2996 | } else { | ||
2997 | b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0); | ||
2998 | } | ||
430 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0); | 2999 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0); |
431 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0); | 3000 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0); |
432 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0); | 3001 | if (dev->phy.rev < 6) { |
433 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0); | 3002 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0); |
3003 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0); | ||
3004 | } | ||
434 | b43_phy_mask(dev, B43_NPHY_RFSEQMODE, | 3005 | b43_phy_mask(dev, B43_NPHY_RFSEQMODE, |
435 | ~(B43_NPHY_RFSEQMODE_CAOVER | | 3006 | ~(B43_NPHY_RFSEQMODE_CAOVER | |
436 | B43_NPHY_RFSEQMODE_TROVER)); | 3007 | B43_NPHY_RFSEQMODE_TROVER)); |
3008 | if (dev->phy.rev >= 3) | ||
3009 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, 0); | ||
437 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0); | 3010 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0); |
438 | 3011 | ||
439 | tmp = (phy->rev < 2) ? 64 : 59; | 3012 | if (dev->phy.rev <= 2) { |
440 | b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, | 3013 | tmp = (dev->phy.rev == 2) ? 0x3B : 0x40; |
441 | ~B43_NPHY_BPHY_CTL3_SCALE, | 3014 | b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, |
442 | tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT); | 3015 | ~B43_NPHY_BPHY_CTL3_SCALE, |
443 | 3016 | tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT); | |
3017 | } | ||
444 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); | 3018 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); |
445 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); | 3019 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); |
446 | 3020 | ||
447 | b43_phy_write(dev, B43_NPHY_TXREALFD, 184); | 3021 | if (bus->sprom.boardflags2_lo & 0x100 || |
448 | b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 200); | 3022 | (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && |
449 | b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 80); | 3023 | bus->boardinfo.type == 0x8B)) |
450 | b43_phy_write(dev, B43_NPHY_C2_BCLIPBKOFF, 511); | 3024 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); |
3025 | else | ||
3026 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8); | ||
3027 | b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 0xC8); | ||
3028 | b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50); | ||
3029 | b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30); | ||
451 | 3030 | ||
452 | //TODO MIMO-Config | 3031 | b43_nphy_update_mimo_config(dev, nphy->preamble_override); |
453 | //TODO Update TX/RX chain | 3032 | b43_nphy_update_txrx_chain(dev); |
454 | 3033 | ||
455 | if (phy->rev < 2) { | 3034 | if (phy->rev < 2) { |
456 | b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); | 3035 | b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); |
457 | b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4); | 3036 | b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4); |
458 | } | 3037 | } |
3038 | |||
3039 | tmp2 = b43_current_band(dev->wl); | ||
3040 | if ((nphy->ipa2g_on && tmp2 == IEEE80211_BAND_2GHZ) || | ||
3041 | (nphy->ipa5g_on && tmp2 == IEEE80211_BAND_5GHZ)) { | ||
3042 | b43_phy_set(dev, B43_NPHY_PAPD_EN0, 0x1); | ||
3043 | b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ0, 0x007F, | ||
3044 | nphy->papd_epsilon_offset[0] << 7); | ||
3045 | b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1); | ||
3046 | b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F, | ||
3047 | nphy->papd_epsilon_offset[1] << 7); | ||
3048 | b43_nphy_int_pa_set_tx_dig_filters(dev); | ||
3049 | } else if (phy->rev >= 5) { | ||
3050 | b43_nphy_ext_pa_set_tx_dig_filters(dev); | ||
3051 | } | ||
3052 | |||
459 | b43_nphy_workarounds(dev); | 3053 | b43_nphy_workarounds(dev); |
460 | b43_nphy_reset_cca(dev); | ||
461 | 3054 | ||
462 | ssb_write32(dev->dev, SSB_TMSLOW, | 3055 | /* Reset CCA, in init code it differs a little from standard way */ |
463 | ssb_read32(dev->dev, SSB_TMSLOW) | B43_TMSLOW_MACPHYCLKEN); | 3056 | b43_nphy_bmac_clock_fgc(dev, 1); |
3057 | tmp = b43_phy_read(dev, B43_NPHY_BBCFG); | ||
3058 | b43_phy_write(dev, B43_NPHY_BBCFG, tmp | B43_NPHY_BBCFG_RSTCCA); | ||
3059 | b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA); | ||
3060 | b43_nphy_bmac_clock_fgc(dev, 0); | ||
3061 | |||
3062 | /* TODO N PHY MAC PHY Clock Set with argument 1 */ | ||
3063 | |||
3064 | b43_nphy_pa_override(dev, false); | ||
464 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); | 3065 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); |
465 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | 3066 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
3067 | b43_nphy_pa_override(dev, true); | ||
3068 | |||
3069 | b43_nphy_classifier(dev, 0, 0); | ||
3070 | b43_nphy_read_clip_detection(dev, clip); | ||
3071 | tx_pwr_state = nphy->txpwrctrl; | ||
3072 | /* TODO N PHY TX power control with argument 0 | ||
3073 | (turning off power control) */ | ||
3074 | /* TODO Fix the TX Power Settings */ | ||
3075 | /* TODO N PHY TX Power Control Idle TSSI */ | ||
3076 | /* TODO N PHY TX Power Control Setup */ | ||
3077 | |||
3078 | if (phy->rev >= 3) { | ||
3079 | /* TODO */ | ||
3080 | } else { | ||
3081 | b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, | ||
3082 | b43_ntab_tx_gain_rev0_1_2); | ||
3083 | b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, | ||
3084 | b43_ntab_tx_gain_rev0_1_2); | ||
3085 | } | ||
3086 | |||
3087 | if (nphy->phyrxchain != 3) | ||
3088 | ;/* TODO N PHY RX Core Set State with phyrxchain as argument */ | ||
3089 | if (nphy->mphase_cal_phase_id > 0) | ||
3090 | ;/* TODO PHY Periodic Calibration Multi-Phase Restart */ | ||
3091 | |||
3092 | do_rssi_cal = false; | ||
3093 | if (phy->rev >= 3) { | ||
3094 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
3095 | do_rssi_cal = (nphy->rssical_chanspec_2G == 0); | ||
3096 | else | ||
3097 | do_rssi_cal = (nphy->rssical_chanspec_5G == 0); | ||
3098 | |||
3099 | if (do_rssi_cal) | ||
3100 | b43_nphy_rssi_cal(dev); | ||
3101 | else | ||
3102 | b43_nphy_restore_rssi_cal(dev); | ||
3103 | } else { | ||
3104 | b43_nphy_rssi_cal(dev); | ||
3105 | } | ||
3106 | |||
3107 | if (!((nphy->measure_hold & 0x6) != 0)) { | ||
3108 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
3109 | do_cal = (nphy->iqcal_chanspec_2G == 0); | ||
3110 | else | ||
3111 | do_cal = (nphy->iqcal_chanspec_5G == 0); | ||
3112 | |||
3113 | if (nphy->mute) | ||
3114 | do_cal = false; | ||
3115 | |||
3116 | if (do_cal) { | ||
3117 | target = b43_nphy_get_tx_gains(dev); | ||
3118 | |||
3119 | if (nphy->antsel_type == 2) | ||
3120 | ;/*TODO NPHY Superswitch Init with argument 1*/ | ||
3121 | if (nphy->perical != 2) { | ||
3122 | b43_nphy_rssi_cal(dev); | ||
3123 | if (phy->rev >= 3) { | ||
3124 | nphy->cal_orig_pwr_idx[0] = | ||
3125 | nphy->txpwrindex[0].index_internal; | ||
3126 | nphy->cal_orig_pwr_idx[1] = | ||
3127 | nphy->txpwrindex[1].index_internal; | ||
3128 | /* TODO N PHY Pre Calibrate TX Gain */ | ||
3129 | target = b43_nphy_get_tx_gains(dev); | ||
3130 | } | ||
3131 | } | ||
3132 | } | ||
3133 | } | ||
3134 | |||
3135 | if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) { | ||
3136 | if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0) | ||
3137 | b43_nphy_save_cal(dev); | ||
3138 | else if (nphy->mphase_cal_phase_id == 0) | ||
3139 | ;/* N PHY Periodic Calibration with argument 3 */ | ||
3140 | } else { | ||
3141 | b43_nphy_restore_cal(dev); | ||
3142 | } | ||
466 | 3143 | ||
467 | b43_phy_read(dev, B43_NPHY_CLASSCTL); /* dummy read */ | 3144 | b43_nphy_tx_pwr_ctrl_coef_setup(dev); |
468 | //TODO read core1/2 clip1 thres regs | 3145 | /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */ |
469 | 3146 | b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015); | |
470 | if (1 /* FIXME Band is 2.4GHz */) | 3147 | b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320); |
471 | b43_nphy_bphy_init(dev); | 3148 | if (phy->rev >= 3 && phy->rev <= 6) |
472 | //TODO disable TX power control | 3149 | b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014); |
473 | //TODO Fix the TX power settings | 3150 | b43_nphy_tx_lp_fbw(dev); |
474 | //TODO Init periodic calibration with reason 3 | 3151 | if (phy->rev >= 3) |
475 | b43_nphy_rssi_cal(dev, 2); | 3152 | b43_nphy_spur_workaround(dev); |
476 | b43_nphy_rssi_cal(dev, 0); | ||
477 | b43_nphy_rssi_cal(dev, 1); | ||
478 | //TODO get TX gain | ||
479 | //TODO init superswitch | ||
480 | //TODO calibrate LO | ||
481 | //TODO idle TSSI TX pctl | ||
482 | //TODO TX power control power setup | ||
483 | //TODO table writes | ||
484 | //TODO TX power control coefficients | ||
485 | //TODO enable TX power control | ||
486 | //TODO control antenna selection | ||
487 | //TODO init radar detection | ||
488 | //TODO reset channel if changed | ||
489 | 3153 | ||
490 | b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); | 3154 | b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); |
491 | return 0; | 3155 | return 0; |
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 1749aef4147d..403aad3f894f 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h | |||
@@ -231,6 +231,7 @@ | |||
231 | #define B43_NPHY_C2_TXIQ_COMP_OFF B43_PHY_N(0x088) /* Core 2 TX I/Q comp offset */ | 231 | #define B43_NPHY_C2_TXIQ_COMP_OFF B43_PHY_N(0x088) /* Core 2 TX I/Q comp offset */ |
232 | #define B43_NPHY_C1_TXCTL B43_PHY_N(0x08B) /* Core 1 TX control */ | 232 | #define B43_NPHY_C1_TXCTL B43_PHY_N(0x08B) /* Core 1 TX control */ |
233 | #define B43_NPHY_C2_TXCTL B43_PHY_N(0x08C) /* Core 2 TX control */ | 233 | #define B43_NPHY_C2_TXCTL B43_PHY_N(0x08C) /* Core 2 TX control */ |
234 | #define B43_NPHY_AFECTL_OVER1 B43_PHY_N(0x08F) /* AFE control override 1 */ | ||
234 | #define B43_NPHY_SCRAM_SIGCTL B43_PHY_N(0x090) /* Scram signal control */ | 235 | #define B43_NPHY_SCRAM_SIGCTL B43_PHY_N(0x090) /* Scram signal control */ |
235 | #define B43_NPHY_SCRAM_SIGCTL_INITST 0x007F /* Initial state value */ | 236 | #define B43_NPHY_SCRAM_SIGCTL_INITST 0x007F /* Initial state value */ |
236 | #define B43_NPHY_SCRAM_SIGCTL_INITST_SHIFT 0 | 237 | #define B43_NPHY_SCRAM_SIGCTL_INITST_SHIFT 0 |
@@ -705,6 +706,10 @@ | |||
705 | #define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power controll init */ | 706 | #define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power controll init */ |
706 | #define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */ | 707 | #define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */ |
707 | #define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0 | 708 | #define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0 |
709 | #define B43_NPHY_PAPD_EN0 B43_PHY_N(0x297) /* PAPD Enable0 TBD */ | ||
710 | #define B43_NPHY_EPS_TABLE_ADJ0 B43_PHY_N(0x298) /* EPS Table Adj0 TBD */ | ||
711 | #define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */ | ||
712 | #define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */ | ||
708 | 713 | ||
709 | 714 | ||
710 | 715 | ||
@@ -919,8 +924,99 @@ | |||
919 | 924 | ||
920 | struct b43_wldev; | 925 | struct b43_wldev; |
921 | 926 | ||
927 | struct b43_phy_n_iq_comp { | ||
928 | s16 a0; | ||
929 | s16 b0; | ||
930 | s16 a1; | ||
931 | s16 b1; | ||
932 | }; | ||
933 | |||
934 | struct b43_phy_n_rssical_cache { | ||
935 | u16 rssical_radio_regs_2G[2]; | ||
936 | u16 rssical_phy_regs_2G[12]; | ||
937 | |||
938 | u16 rssical_radio_regs_5G[2]; | ||
939 | u16 rssical_phy_regs_5G[12]; | ||
940 | }; | ||
941 | |||
942 | struct b43_phy_n_cal_cache { | ||
943 | u16 txcal_radio_regs_2G[8]; | ||
944 | u16 txcal_coeffs_2G[8]; | ||
945 | struct b43_phy_n_iq_comp rxcal_coeffs_2G; | ||
946 | |||
947 | u16 txcal_radio_regs_5G[8]; | ||
948 | u16 txcal_coeffs_5G[8]; | ||
949 | struct b43_phy_n_iq_comp rxcal_coeffs_5G; | ||
950 | }; | ||
951 | |||
952 | struct b43_phy_n_txpwrindex { | ||
953 | s8 index; | ||
954 | s8 index_internal; | ||
955 | s8 index_internal_save; | ||
956 | u16 AfectrlOverride; | ||
957 | u16 AfeCtrlDacGain; | ||
958 | u16 rad_gain; | ||
959 | u8 bbmult; | ||
960 | u16 iqcomp_a; | ||
961 | u16 iqcomp_b; | ||
962 | u16 locomp; | ||
963 | }; | ||
964 | |||
922 | struct b43_phy_n { | 965 | struct b43_phy_n { |
923 | //TODO lots of missing stuff | 966 | u8 antsel_type; |
967 | u8 cal_orig_pwr_idx[2]; | ||
968 | u8 measure_hold; | ||
969 | u8 phyrxchain; | ||
970 | u8 perical; | ||
971 | u32 deaf_count; | ||
972 | u32 rxcalparams; | ||
973 | bool hang_avoid; | ||
974 | bool mute; | ||
975 | u16 papd_epsilon_offset[2]; | ||
976 | s32 preamble_override; | ||
977 | u32 bb_mult_save; | ||
978 | u16 radio_chanspec; | ||
979 | |||
980 | bool gain_boost; | ||
981 | bool elna_gain_config; | ||
982 | bool band5g_pwrgain; | ||
983 | |||
984 | u8 mphase_cal_phase_id; | ||
985 | u16 mphase_txcal_cmdidx; | ||
986 | u16 mphase_txcal_numcmds; | ||
987 | u16 mphase_txcal_bestcoeffs[11]; | ||
988 | |||
989 | u8 txpwrctrl; | ||
990 | u16 txcal_bbmult; | ||
991 | u16 txiqlocal_bestc[11]; | ||
992 | bool txiqlocal_coeffsvalid; | ||
993 | struct b43_phy_n_txpwrindex txpwrindex[2]; | ||
994 | |||
995 | u8 txrx_chain; | ||
996 | u16 tx_rx_cal_phy_saveregs[11]; | ||
997 | u16 tx_rx_cal_radio_saveregs[22]; | ||
998 | |||
999 | u16 rfctrl_intc1_save; | ||
1000 | u16 rfctrl_intc2_save; | ||
1001 | |||
1002 | u16 classifier_state; | ||
1003 | u16 clip_state[2]; | ||
1004 | |||
1005 | bool aband_spurwar_en; | ||
1006 | bool gband_spurwar_en; | ||
1007 | |||
1008 | bool ipa2g_on; | ||
1009 | u8 iqcal_chanspec_2G; | ||
1010 | u8 rssical_chanspec_2G; | ||
1011 | |||
1012 | bool ipa5g_on; | ||
1013 | u8 iqcal_chanspec_5G; | ||
1014 | u8 rssical_chanspec_5G; | ||
1015 | |||
1016 | struct b43_phy_n_rssical_cache rssical_cache; | ||
1017 | struct b43_phy_n_cal_cache cal_cache; | ||
1018 | bool crsminpwr_adjusted; | ||
1019 | bool noisevars_adjusted; | ||
924 | }; | 1020 | }; |
925 | 1021 | ||
926 | 1022 | ||
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 9b9044400218..aa12273ae716 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/slab.h> | ||
34 | 35 | ||
35 | 36 | ||
36 | static u16 generate_cookie(struct b43_pio_txqueue *q, | 37 | static u16 generate_cookie(struct b43_pio_txqueue *q, |
@@ -342,12 +343,15 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, | |||
342 | q->mmio_base + B43_PIO_TXDATA, | 343 | q->mmio_base + B43_PIO_TXDATA, |
343 | sizeof(u16)); | 344 | sizeof(u16)); |
344 | if (data_len & 1) { | 345 | if (data_len & 1) { |
346 | u8 *tail = wl->pio_tailspace; | ||
347 | BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2); | ||
348 | |||
345 | /* Write the last byte. */ | 349 | /* Write the last byte. */ |
346 | ctl &= ~B43_PIO_TXCTL_WRITEHI; | 350 | ctl &= ~B43_PIO_TXCTL_WRITEHI; |
347 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); | 351 | b43_piotx_write16(q, B43_PIO_TXCTL, ctl); |
348 | wl->tx_tail[0] = data[data_len - 1]; | 352 | tail[0] = data[data_len - 1]; |
349 | wl->tx_tail[1] = 0; | 353 | tail[1] = 0; |
350 | ssb_block_write(dev->dev, wl->tx_tail, 2, | 354 | ssb_block_write(dev->dev, tail, 2, |
351 | q->mmio_base + B43_PIO_TXDATA, | 355 | q->mmio_base + B43_PIO_TXDATA, |
352 | sizeof(u16)); | 356 | sizeof(u16)); |
353 | } | 357 | } |
@@ -393,31 +397,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, | |||
393 | q->mmio_base + B43_PIO8_TXDATA, | 397 | q->mmio_base + B43_PIO8_TXDATA, |
394 | sizeof(u32)); | 398 | sizeof(u32)); |
395 | if (data_len & 3) { | 399 | if (data_len & 3) { |
396 | wl->tx_tail[3] = 0; | 400 | u8 *tail = wl->pio_tailspace; |
401 | BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4); | ||
402 | |||
403 | memset(tail, 0, 4); | ||
397 | /* Write the last few bytes. */ | 404 | /* Write the last few bytes. */ |
398 | ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | | 405 | ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | |
399 | B43_PIO8_TXCTL_24_31); | 406 | B43_PIO8_TXCTL_24_31); |
400 | switch (data_len & 3) { | 407 | switch (data_len & 3) { |
401 | case 3: | 408 | case 3: |
402 | ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15; | 409 | ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15; |
403 | wl->tx_tail[0] = data[data_len - 3]; | 410 | tail[0] = data[data_len - 3]; |
404 | wl->tx_tail[1] = data[data_len - 2]; | 411 | tail[1] = data[data_len - 2]; |
405 | wl->tx_tail[2] = data[data_len - 1]; | 412 | tail[2] = data[data_len - 1]; |
406 | break; | 413 | break; |
407 | case 2: | 414 | case 2: |
408 | ctl |= B43_PIO8_TXCTL_8_15; | 415 | ctl |= B43_PIO8_TXCTL_8_15; |
409 | wl->tx_tail[0] = data[data_len - 2]; | 416 | tail[0] = data[data_len - 2]; |
410 | wl->tx_tail[1] = data[data_len - 1]; | 417 | tail[1] = data[data_len - 1]; |
411 | wl->tx_tail[2] = 0; | ||
412 | break; | 418 | break; |
413 | case 1: | 419 | case 1: |
414 | wl->tx_tail[0] = data[data_len - 1]; | 420 | tail[0] = data[data_len - 1]; |
415 | wl->tx_tail[1] = 0; | ||
416 | wl->tx_tail[2] = 0; | ||
417 | break; | 421 | break; |
418 | } | 422 | } |
419 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); | 423 | b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); |
420 | ssb_block_write(dev->dev, wl->tx_tail, 4, | 424 | ssb_block_write(dev->dev, tail, 4, |
421 | q->mmio_base + B43_PIO8_TXDATA, | 425 | q->mmio_base + B43_PIO8_TXDATA, |
422 | sizeof(u32)); | 426 | sizeof(u32)); |
423 | } | 427 | } |
@@ -456,6 +460,7 @@ static int pio_tx_frame(struct b43_pio_txqueue *q, | |||
456 | int err; | 460 | int err; |
457 | unsigned int hdrlen; | 461 | unsigned int hdrlen; |
458 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 462 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
463 | struct b43_txhdr *txhdr = (struct b43_txhdr *)wl->pio_scratchspace; | ||
459 | 464 | ||
460 | B43_WARN_ON(list_empty(&q->packets_list)); | 465 | B43_WARN_ON(list_empty(&q->packets_list)); |
461 | pack = list_entry(q->packets_list.next, | 466 | pack = list_entry(q->packets_list.next, |
@@ -463,7 +468,9 @@ static int pio_tx_frame(struct b43_pio_txqueue *q, | |||
463 | 468 | ||
464 | cookie = generate_cookie(q, pack); | 469 | cookie = generate_cookie(q, pack); |
465 | hdrlen = b43_txhdr_size(dev); | 470 | hdrlen = b43_txhdr_size(dev); |
466 | err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb, | 471 | BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(struct b43_txhdr)); |
472 | B43_WARN_ON(sizeof(wl->pio_scratchspace) < hdrlen); | ||
473 | err = b43_generate_txhdr(dev, (u8 *)txhdr, skb, | ||
467 | info, cookie); | 474 | info, cookie); |
468 | if (err) | 475 | if (err) |
469 | return err; | 476 | return err; |
@@ -477,9 +484,9 @@ static int pio_tx_frame(struct b43_pio_txqueue *q, | |||
477 | 484 | ||
478 | pack->skb = skb; | 485 | pack->skb = skb; |
479 | if (q->rev >= 8) | 486 | if (q->rev >= 8) |
480 | pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen); | 487 | pio_tx_frame_4byte_queue(pack, (const u8 *)txhdr, hdrlen); |
481 | else | 488 | else |
482 | pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen); | 489 | pio_tx_frame_2byte_queue(pack, (const u8 *)txhdr, hdrlen); |
483 | 490 | ||
484 | /* Remove it from the list of available packet slots. | 491 | /* Remove it from the list of available packet slots. |
485 | * It will be put back when we receive the status report. */ | 492 | * It will be put back when we receive the status report. */ |
@@ -553,7 +560,6 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) | |||
553 | b43err(dev->wl, "PIO transmission failure\n"); | 560 | b43err(dev->wl, "PIO transmission failure\n"); |
554 | goto out; | 561 | goto out; |
555 | } | 562 | } |
556 | q->nr_tx_packets++; | ||
557 | 563 | ||
558 | B43_WARN_ON(q->buffer_used > q->buffer_size); | 564 | B43_WARN_ON(q->buffer_used > q->buffer_size); |
559 | if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || | 565 | if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || |
@@ -599,22 +605,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev, | |||
599 | } | 605 | } |
600 | } | 606 | } |
601 | 607 | ||
602 | void b43_pio_get_tx_stats(struct b43_wldev *dev, | ||
603 | struct ieee80211_tx_queue_stats *stats) | ||
604 | { | ||
605 | const int nr_queues = dev->wl->hw->queues; | ||
606 | struct b43_pio_txqueue *q; | ||
607 | int i; | ||
608 | |||
609 | for (i = 0; i < nr_queues; i++) { | ||
610 | q = select_queue_by_priority(dev, i); | ||
611 | |||
612 | stats[i].len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots; | ||
613 | stats[i].limit = B43_PIO_MAX_NR_TXPACKETS; | ||
614 | stats[i].count = q->nr_tx_packets; | ||
615 | } | ||
616 | } | ||
617 | |||
618 | /* Returns whether we should fetch another frame. */ | 608 | /* Returns whether we should fetch another frame. */ |
619 | static bool pio_rx_frame(struct b43_pio_rxqueue *q) | 609 | static bool pio_rx_frame(struct b43_pio_rxqueue *q) |
620 | { | 610 | { |
@@ -625,8 +615,11 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q) | |||
625 | unsigned int i, padding; | 615 | unsigned int i, padding; |
626 | struct sk_buff *skb; | 616 | struct sk_buff *skb; |
627 | const char *err_msg = NULL; | 617 | const char *err_msg = NULL; |
618 | struct b43_rxhdr_fw4 *rxhdr = | ||
619 | (struct b43_rxhdr_fw4 *)wl->pio_scratchspace; | ||
628 | 620 | ||
629 | memset(&wl->rxhdr, 0, sizeof(wl->rxhdr)); | 621 | BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(*rxhdr)); |
622 | memset(rxhdr, 0, sizeof(*rxhdr)); | ||
630 | 623 | ||
631 | /* Check if we have data and wait for it to get ready. */ | 624 | /* Check if we have data and wait for it to get ready. */ |
632 | if (q->rev >= 8) { | 625 | if (q->rev >= 8) { |
@@ -664,16 +657,16 @@ data_ready: | |||
664 | 657 | ||
665 | /* Get the preamble (RX header) */ | 658 | /* Get the preamble (RX header) */ |
666 | if (q->rev >= 8) { | 659 | if (q->rev >= 8) { |
667 | ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr), | 660 | ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), |
668 | q->mmio_base + B43_PIO8_RXDATA, | 661 | q->mmio_base + B43_PIO8_RXDATA, |
669 | sizeof(u32)); | 662 | sizeof(u32)); |
670 | } else { | 663 | } else { |
671 | ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr), | 664 | ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), |
672 | q->mmio_base + B43_PIO_RXDATA, | 665 | q->mmio_base + B43_PIO_RXDATA, |
673 | sizeof(u16)); | 666 | sizeof(u16)); |
674 | } | 667 | } |
675 | /* Sanity checks. */ | 668 | /* Sanity checks. */ |
676 | len = le16_to_cpu(wl->rxhdr.frame_len); | 669 | len = le16_to_cpu(rxhdr->frame_len); |
677 | if (unlikely(len > 0x700)) { | 670 | if (unlikely(len > 0x700)) { |
678 | err_msg = "len > 0x700"; | 671 | err_msg = "len > 0x700"; |
679 | goto rx_error; | 672 | goto rx_error; |
@@ -683,7 +676,7 @@ data_ready: | |||
683 | goto rx_error; | 676 | goto rx_error; |
684 | } | 677 | } |
685 | 678 | ||
686 | macstat = le32_to_cpu(wl->rxhdr.mac_status); | 679 | macstat = le32_to_cpu(rxhdr->mac_status); |
687 | if (macstat & B43_RX_MAC_FCSERR) { | 680 | if (macstat & B43_RX_MAC_FCSERR) { |
688 | if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) { | 681 | if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) { |
689 | /* Drop frames with failed FCS. */ | 682 | /* Drop frames with failed FCS. */ |
@@ -708,22 +701,25 @@ data_ready: | |||
708 | q->mmio_base + B43_PIO8_RXDATA, | 701 | q->mmio_base + B43_PIO8_RXDATA, |
709 | sizeof(u32)); | 702 | sizeof(u32)); |
710 | if (len & 3) { | 703 | if (len & 3) { |
704 | u8 *tail = wl->pio_tailspace; | ||
705 | BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4); | ||
706 | |||
711 | /* Read the last few bytes. */ | 707 | /* Read the last few bytes. */ |
712 | ssb_block_read(dev->dev, wl->rx_tail, 4, | 708 | ssb_block_read(dev->dev, tail, 4, |
713 | q->mmio_base + B43_PIO8_RXDATA, | 709 | q->mmio_base + B43_PIO8_RXDATA, |
714 | sizeof(u32)); | 710 | sizeof(u32)); |
715 | switch (len & 3) { | 711 | switch (len & 3) { |
716 | case 3: | 712 | case 3: |
717 | skb->data[len + padding - 3] = wl->rx_tail[0]; | 713 | skb->data[len + padding - 3] = tail[0]; |
718 | skb->data[len + padding - 2] = wl->rx_tail[1]; | 714 | skb->data[len + padding - 2] = tail[1]; |
719 | skb->data[len + padding - 1] = wl->rx_tail[2]; | 715 | skb->data[len + padding - 1] = tail[2]; |
720 | break; | 716 | break; |
721 | case 2: | 717 | case 2: |
722 | skb->data[len + padding - 2] = wl->rx_tail[0]; | 718 | skb->data[len + padding - 2] = tail[0]; |
723 | skb->data[len + padding - 1] = wl->rx_tail[1]; | 719 | skb->data[len + padding - 1] = tail[1]; |
724 | break; | 720 | break; |
725 | case 1: | 721 | case 1: |
726 | skb->data[len + padding - 1] = wl->rx_tail[0]; | 722 | skb->data[len + padding - 1] = tail[0]; |
727 | break; | 723 | break; |
728 | } | 724 | } |
729 | } | 725 | } |
@@ -732,22 +728,29 @@ data_ready: | |||
732 | q->mmio_base + B43_PIO_RXDATA, | 728 | q->mmio_base + B43_PIO_RXDATA, |
733 | sizeof(u16)); | 729 | sizeof(u16)); |
734 | if (len & 1) { | 730 | if (len & 1) { |
731 | u8 *tail = wl->pio_tailspace; | ||
732 | BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2); | ||
733 | |||
735 | /* Read the last byte. */ | 734 | /* Read the last byte. */ |
736 | ssb_block_read(dev->dev, wl->rx_tail, 2, | 735 | ssb_block_read(dev->dev, tail, 2, |
737 | q->mmio_base + B43_PIO_RXDATA, | 736 | q->mmio_base + B43_PIO_RXDATA, |
738 | sizeof(u16)); | 737 | sizeof(u16)); |
739 | skb->data[len + padding - 1] = wl->rx_tail[0]; | 738 | skb->data[len + padding - 1] = tail[0]; |
740 | } | 739 | } |
741 | } | 740 | } |
742 | 741 | ||
743 | b43_rx(q->dev, skb, &wl->rxhdr); | 742 | b43_rx(q->dev, skb, rxhdr); |
744 | 743 | ||
745 | return 1; | 744 | return 1; |
746 | 745 | ||
747 | rx_error: | 746 | rx_error: |
748 | if (err_msg) | 747 | if (err_msg) |
749 | b43dbg(q->dev->wl, "PIO RX error: %s\n", err_msg); | 748 | b43dbg(q->dev->wl, "PIO RX error: %s\n", err_msg); |
750 | b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY); | 749 | if (q->rev >= 8) |
750 | b43_piorx_write32(q, B43_PIO8_RXCTL, B43_PIO8_RXCTL_DATARDY); | ||
751 | else | ||
752 | b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY); | ||
753 | |||
751 | return 1; | 754 | return 1; |
752 | } | 755 | } |
753 | 756 | ||
diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h index 7dd649c9ddad..1e516147424f 100644 --- a/drivers/net/wireless/b43/pio.h +++ b/drivers/net/wireless/b43/pio.h | |||
@@ -55,8 +55,6 @@ | |||
55 | #define B43_PIO_MAX_NR_TXPACKETS 32 | 55 | #define B43_PIO_MAX_NR_TXPACKETS 32 |
56 | 56 | ||
57 | 57 | ||
58 | #ifdef CONFIG_B43_PIO | ||
59 | |||
60 | struct b43_pio_txpacket { | 58 | struct b43_pio_txpacket { |
61 | /* Pointer to the TX queue we belong to. */ | 59 | /* Pointer to the TX queue we belong to. */ |
62 | struct b43_pio_txqueue *queue; | 60 | struct b43_pio_txqueue *queue; |
@@ -92,9 +90,6 @@ struct b43_pio_txqueue { | |||
92 | struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS]; | 90 | struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS]; |
93 | struct list_head packets_list; | 91 | struct list_head packets_list; |
94 | 92 | ||
95 | /* Total number of transmitted packets. */ | ||
96 | unsigned int nr_tx_packets; | ||
97 | |||
98 | /* Shortcut to the 802.11 core revision. This is to | 93 | /* Shortcut to the 802.11 core revision. This is to |
99 | * avoid horrible pointer dereferencing in the fastpaths. */ | 94 | * avoid horrible pointer dereferencing in the fastpaths. */ |
100 | u8 rev; | 95 | u8 rev; |
@@ -162,49 +157,9 @@ void b43_pio_free(struct b43_wldev *dev); | |||
162 | 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); |
163 | void b43_pio_handle_txstatus(struct b43_wldev *dev, | 158 | void b43_pio_handle_txstatus(struct b43_wldev *dev, |
164 | const struct b43_txstatus *status); | 159 | const struct b43_txstatus *status); |
165 | void b43_pio_get_tx_stats(struct b43_wldev *dev, | ||
166 | struct ieee80211_tx_queue_stats *stats); | ||
167 | void b43_pio_rx(struct b43_pio_rxqueue *q); | 160 | void b43_pio_rx(struct b43_pio_rxqueue *q); |
168 | 161 | ||
169 | void b43_pio_tx_suspend(struct b43_wldev *dev); | 162 | void b43_pio_tx_suspend(struct b43_wldev *dev); |
170 | void b43_pio_tx_resume(struct b43_wldev *dev); | 163 | void b43_pio_tx_resume(struct b43_wldev *dev); |
171 | 164 | ||
172 | |||
173 | #else /* CONFIG_B43_PIO */ | ||
174 | |||
175 | |||
176 | static inline int b43_pio_init(struct b43_wldev *dev) | ||
177 | { | ||
178 | return 0; | ||
179 | } | ||
180 | static inline void b43_pio_free(struct b43_wldev *dev) | ||
181 | { | ||
182 | } | ||
183 | static inline void b43_pio_stop(struct b43_wldev *dev) | ||
184 | { | ||
185 | } | ||
186 | static inline int b43_pio_tx(struct b43_wldev *dev, | ||
187 | struct sk_buff *skb) | ||
188 | { | ||
189 | return 0; | ||
190 | } | ||
191 | static inline void b43_pio_handle_txstatus(struct b43_wldev *dev, | ||
192 | const struct b43_txstatus *status) | ||
193 | { | ||
194 | } | ||
195 | static inline void b43_pio_get_tx_stats(struct b43_wldev *dev, | ||
196 | struct ieee80211_tx_queue_stats *stats) | ||
197 | { | ||
198 | } | ||
199 | static inline void b43_pio_rx(struct b43_pio_rxqueue *q) | ||
200 | { | ||
201 | } | ||
202 | static inline void b43_pio_tx_suspend(struct b43_wldev *dev) | ||
203 | { | ||
204 | } | ||
205 | static inline void b43_pio_tx_resume(struct b43_wldev *dev) | ||
206 | { | ||
207 | } | ||
208 | |||
209 | #endif /* CONFIG_B43_PIO */ | ||
210 | #endif /* B43_PIO_H_ */ | 165 | #endif /* B43_PIO_H_ */ |
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index ffdce6f3c909..78016ae21c50 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c | |||
@@ -33,8 +33,14 @@ bool b43_is_hw_radio_enabled(struct b43_wldev *dev) | |||
33 | & B43_MMIO_RADIO_HWENABLED_HI_MASK)) | 33 | & B43_MMIO_RADIO_HWENABLED_HI_MASK)) |
34 | return 1; | 34 | return 1; |
35 | } else { | 35 | } else { |
36 | if (b43_status(dev) >= B43_STAT_STARTED && | 36 | /* To prevent CPU fault on PPC, do not read a register |
37 | b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO) | 37 | * unless the interface is started; however, on resume |
38 | * for hibernation, this routine is entered early. When | ||
39 | * that happens, unconditionally return TRUE. | ||
40 | */ | ||
41 | if (b43_status(dev) < B43_STAT_STARTED) | ||
42 | return 1; | ||
43 | if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO) | ||
38 | & B43_MMIO_RADIO_HWENABLED_LO_MASK) | 44 | & B43_MMIO_RADIO_HWENABLED_LO_MASK) |
39 | return 1; | 45 | return 1; |
40 | } | 46 | } |
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 0d3ac64147a5..4e56b7bbcebd 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/mmc/card.h> | 16 | #include <linux/mmc/card.h> |
17 | #include <linux/mmc/sdio_func.h> | 17 | #include <linux/mmc/sdio_func.h> |
18 | #include <linux/mmc/sdio_ids.h> | 18 | #include <linux/mmc/sdio_ids.h> |
19 | #include <linux/slab.h> | ||
19 | #include <linux/ssb/ssb.h> | 20 | #include <linux/ssb/ssb.h> |
20 | 21 | ||
21 | #include "sdio.h" | 22 | #include "sdio.h" |
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 4e2336315545..a00d509150f7 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c | |||
@@ -1336,7 +1336,7 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel) | |||
1336 | } | 1336 | } |
1337 | 1337 | ||
1338 | 1338 | ||
1339 | const u8 b43_ntab_adjustpower0[] = { | 1339 | static const u8 b43_ntab_adjustpower0[] = { |
1340 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, | 1340 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, |
1341 | 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, | 1341 | 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, |
1342 | 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, | 1342 | 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, |
@@ -1355,7 +1355,7 @@ const u8 b43_ntab_adjustpower0[] = { | |||
1355 | 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, | 1355 | 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, |
1356 | }; | 1356 | }; |
1357 | 1357 | ||
1358 | const u8 b43_ntab_adjustpower1[] = { | 1358 | static const u8 b43_ntab_adjustpower1[] = { |
1359 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, | 1359 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, |
1360 | 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, | 1360 | 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, |
1361 | 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, | 1361 | 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, |
@@ -1374,11 +1374,11 @@ const u8 b43_ntab_adjustpower1[] = { | |||
1374 | 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, | 1374 | 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, |
1375 | }; | 1375 | }; |
1376 | 1376 | ||
1377 | const u16 b43_ntab_bdi[] = { | 1377 | static const u16 b43_ntab_bdi[] = { |
1378 | 0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2, | 1378 | 0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2, |
1379 | }; | 1379 | }; |
1380 | 1380 | ||
1381 | const u32 b43_ntab_channelest[] = { | 1381 | static const u32 b43_ntab_channelest[] = { |
1382 | 0x44444444, 0x44444444, 0x44444444, 0x44444444, | 1382 | 0x44444444, 0x44444444, 0x44444444, 0x44444444, |
1383 | 0x44444444, 0x44444444, 0x44444444, 0x44444444, | 1383 | 0x44444444, 0x44444444, 0x44444444, 0x44444444, |
1384 | 0x10101010, 0x10101010, 0x10101010, 0x10101010, | 1384 | 0x10101010, 0x10101010, 0x10101010, 0x10101010, |
@@ -1405,7 +1405,7 @@ const u32 b43_ntab_channelest[] = { | |||
1405 | 0x10101010, 0x10101010, 0x10101010, 0x10101010, | 1405 | 0x10101010, 0x10101010, 0x10101010, 0x10101010, |
1406 | }; | 1406 | }; |
1407 | 1407 | ||
1408 | const u8 b43_ntab_estimatepowerlt0[] = { | 1408 | static const u8 b43_ntab_estimatepowerlt0[] = { |
1409 | 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, | 1409 | 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, |
1410 | 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, | 1410 | 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, |
1411 | 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, | 1411 | 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, |
@@ -1416,7 +1416,7 @@ const u8 b43_ntab_estimatepowerlt0[] = { | |||
1416 | 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, | 1416 | 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, |
1417 | }; | 1417 | }; |
1418 | 1418 | ||
1419 | const u8 b43_ntab_estimatepowerlt1[] = { | 1419 | static const u8 b43_ntab_estimatepowerlt1[] = { |
1420 | 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, | 1420 | 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, |
1421 | 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, | 1421 | 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, |
1422 | 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, | 1422 | 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, |
@@ -1427,14 +1427,14 @@ const u8 b43_ntab_estimatepowerlt1[] = { | |||
1427 | 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, | 1427 | 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, |
1428 | }; | 1428 | }; |
1429 | 1429 | ||
1430 | const u8 b43_ntab_framelookup[] = { | 1430 | static const u8 b43_ntab_framelookup[] = { |
1431 | 0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16, | 1431 | 0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16, |
1432 | 0x0A, 0x0C, 0x1C, 0x1C, 0x0B, 0x0D, 0x1E, 0x1E, | 1432 | 0x0A, 0x0C, 0x1C, 0x1C, 0x0B, 0x0D, 0x1E, 0x1E, |
1433 | 0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1A, 0x1A, | 1433 | 0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1A, 0x1A, |
1434 | 0x0E, 0x10, 0x20, 0x28, 0x0F, 0x11, 0x22, 0x2A, | 1434 | 0x0E, 0x10, 0x20, 0x28, 0x0F, 0x11, 0x22, 0x2A, |
1435 | }; | 1435 | }; |
1436 | 1436 | ||
1437 | const u32 b43_ntab_framestruct[] = { | 1437 | static const u32 b43_ntab_framestruct[] = { |
1438 | 0x08004A04, 0x00100000, 0x01000A05, 0x00100020, | 1438 | 0x08004A04, 0x00100000, 0x01000A05, 0x00100020, |
1439 | 0x09804506, 0x00100030, 0x09804507, 0x00100030, | 1439 | 0x09804506, 0x00100030, 0x09804507, 0x00100030, |
1440 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 1440 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
@@ -1645,7 +1645,7 @@ const u32 b43_ntab_framestruct[] = { | |||
1645 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 1645 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
1646 | }; | 1646 | }; |
1647 | 1647 | ||
1648 | const u32 b43_ntab_gainctl0[] = { | 1648 | static const u32 b43_ntab_gainctl0[] = { |
1649 | 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, | 1649 | 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, |
1650 | 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, | 1650 | 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, |
1651 | 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, | 1651 | 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, |
@@ -1680,7 +1680,7 @@ const u32 b43_ntab_gainctl0[] = { | |||
1680 | 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, | 1680 | 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, |
1681 | }; | 1681 | }; |
1682 | 1682 | ||
1683 | const u32 b43_ntab_gainctl1[] = { | 1683 | static const u32 b43_ntab_gainctl1[] = { |
1684 | 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, | 1684 | 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, |
1685 | 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, | 1685 | 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, |
1686 | 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, | 1686 | 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, |
@@ -1715,12 +1715,12 @@ const u32 b43_ntab_gainctl1[] = { | |||
1715 | 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, | 1715 | 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, |
1716 | }; | 1716 | }; |
1717 | 1717 | ||
1718 | const u32 b43_ntab_intlevel[] = { | 1718 | static const u32 b43_ntab_intlevel[] = { |
1719 | 0x00802070, 0x0671188D, 0x0A60192C, 0x0A300E46, | 1719 | 0x00802070, 0x0671188D, 0x0A60192C, 0x0A300E46, |
1720 | 0x00C1188D, 0x080024D2, 0x00000070, | 1720 | 0x00C1188D, 0x080024D2, 0x00000070, |
1721 | }; | 1721 | }; |
1722 | 1722 | ||
1723 | const u32 b43_ntab_iqlt0[] = { | 1723 | static const u32 b43_ntab_iqlt0[] = { |
1724 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, | 1724 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, |
1725 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, | 1725 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, |
1726 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, | 1726 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, |
@@ -1755,7 +1755,7 @@ const u32 b43_ntab_iqlt0[] = { | |||
1755 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, | 1755 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, |
1756 | }; | 1756 | }; |
1757 | 1757 | ||
1758 | const u32 b43_ntab_iqlt1[] = { | 1758 | static const u32 b43_ntab_iqlt1[] = { |
1759 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, | 1759 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, |
1760 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, | 1760 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, |
1761 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, | 1761 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, |
@@ -1790,7 +1790,7 @@ const u32 b43_ntab_iqlt1[] = { | |||
1790 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, | 1790 | 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, |
1791 | }; | 1791 | }; |
1792 | 1792 | ||
1793 | const u16 b43_ntab_loftlt0[] = { | 1793 | static const u16 b43_ntab_loftlt0[] = { |
1794 | 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, | 1794 | 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, |
1795 | 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103, | 1795 | 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103, |
1796 | 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, | 1796 | 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, |
@@ -1815,7 +1815,7 @@ const u16 b43_ntab_loftlt0[] = { | |||
1815 | 0x0002, 0x0103, | 1815 | 0x0002, 0x0103, |
1816 | }; | 1816 | }; |
1817 | 1817 | ||
1818 | const u16 b43_ntab_loftlt1[] = { | 1818 | static const u16 b43_ntab_loftlt1[] = { |
1819 | 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, | 1819 | 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, |
1820 | 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103, | 1820 | 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103, |
1821 | 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, | 1821 | 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, |
@@ -1840,7 +1840,7 @@ const u16 b43_ntab_loftlt1[] = { | |||
1840 | 0x0002, 0x0103, | 1840 | 0x0002, 0x0103, |
1841 | }; | 1841 | }; |
1842 | 1842 | ||
1843 | const u8 b43_ntab_mcs[] = { | 1843 | static const u8 b43_ntab_mcs[] = { |
1844 | 0x00, 0x08, 0x0A, 0x10, 0x12, 0x19, 0x1A, 0x1C, | 1844 | 0x00, 0x08, 0x0A, 0x10, 0x12, 0x19, 0x1A, 0x1C, |
1845 | 0x40, 0x48, 0x4A, 0x50, 0x52, 0x59, 0x5A, 0x5C, | 1845 | 0x40, 0x48, 0x4A, 0x50, 0x52, 0x59, 0x5A, 0x5C, |
1846 | 0x80, 0x88, 0x8A, 0x90, 0x92, 0x99, 0x9A, 0x9C, | 1846 | 0x80, 0x88, 0x8A, 0x90, 0x92, 0x99, 0x9A, 0x9C, |
@@ -1859,7 +1859,7 @@ const u8 b43_ntab_mcs[] = { | |||
1859 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 1859 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1860 | }; | 1860 | }; |
1861 | 1861 | ||
1862 | const u32 b43_ntab_noisevar10[] = { | 1862 | static const u32 b43_ntab_noisevar10[] = { |
1863 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, | 1863 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, |
1864 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, | 1864 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, |
1865 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, | 1865 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, |
@@ -1926,7 +1926,7 @@ const u32 b43_ntab_noisevar10[] = { | |||
1926 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, | 1926 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, |
1927 | }; | 1927 | }; |
1928 | 1928 | ||
1929 | const u32 b43_ntab_noisevar11[] = { | 1929 | static const u32 b43_ntab_noisevar11[] = { |
1930 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, | 1930 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, |
1931 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, | 1931 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, |
1932 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, | 1932 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, |
@@ -1993,7 +1993,7 @@ const u32 b43_ntab_noisevar11[] = { | |||
1993 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, | 1993 | 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, |
1994 | }; | 1994 | }; |
1995 | 1995 | ||
1996 | const u16 b43_ntab_pilot[] = { | 1996 | static const u16 b43_ntab_pilot[] = { |
1997 | 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, | 1997 | 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, |
1998 | 0xFF08, 0xFF08, 0x80D5, 0x80D5, 0x80D5, 0x80D5, | 1998 | 0xFF08, 0xFF08, 0x80D5, 0x80D5, 0x80D5, 0x80D5, |
1999 | 0x80D5, 0x80D5, 0x80D5, 0x80D5, 0xFF0A, 0xFF82, | 1999 | 0x80D5, 0x80D5, 0x80D5, 0x80D5, 0xFF0A, 0xFF82, |
@@ -2011,12 +2011,12 @@ const u16 b43_ntab_pilot[] = { | |||
2011 | 0xF0A0, 0xF028, 0xFFFF, 0xFFFF, | 2011 | 0xF0A0, 0xF028, 0xFFFF, 0xFFFF, |
2012 | }; | 2012 | }; |
2013 | 2013 | ||
2014 | const u32 b43_ntab_pilotlt[] = { | 2014 | static const u32 b43_ntab_pilotlt[] = { |
2015 | 0x76540123, 0x62407351, 0x76543201, 0x76540213, | 2015 | 0x76540123, 0x62407351, 0x76543201, 0x76540213, |
2016 | 0x76540123, 0x76430521, | 2016 | 0x76540123, 0x76430521, |
2017 | }; | 2017 | }; |
2018 | 2018 | ||
2019 | const u32 b43_ntab_tdi20a0[] = { | 2019 | static const u32 b43_ntab_tdi20a0[] = { |
2020 | 0x00091226, 0x000A1429, 0x000B56AD, 0x000C58B0, | 2020 | 0x00091226, 0x000A1429, 0x000B56AD, 0x000C58B0, |
2021 | 0x000D5AB3, 0x000E9CB6, 0x000F9EBA, 0x0000C13D, | 2021 | 0x000D5AB3, 0x000E9CB6, 0x000F9EBA, 0x0000C13D, |
2022 | 0x00020301, 0x00030504, 0x00040708, 0x0005090B, | 2022 | 0x00020301, 0x00030504, 0x00040708, 0x0005090B, |
@@ -2033,7 +2033,7 @@ const u32 b43_ntab_tdi20a0[] = { | |||
2033 | 0x00000000, 0x00000000, 0x00000000, | 2033 | 0x00000000, 0x00000000, 0x00000000, |
2034 | }; | 2034 | }; |
2035 | 2035 | ||
2036 | const u32 b43_ntab_tdi20a1[] = { | 2036 | static const u32 b43_ntab_tdi20a1[] = { |
2037 | 0x00014B26, 0x00028D29, 0x000393AD, 0x00049630, | 2037 | 0x00014B26, 0x00028D29, 0x000393AD, 0x00049630, |
2038 | 0x0005D833, 0x0006DA36, 0x00099C3A, 0x000A9E3D, | 2038 | 0x0005D833, 0x0006DA36, 0x00099C3A, 0x000A9E3D, |
2039 | 0x000BC081, 0x000CC284, 0x000DC488, 0x000F068B, | 2039 | 0x000BC081, 0x000CC284, 0x000DC488, 0x000F068B, |
@@ -2050,7 +2050,7 @@ const u32 b43_ntab_tdi20a1[] = { | |||
2050 | 0x00000000, 0x00000000, 0x00000000, | 2050 | 0x00000000, 0x00000000, 0x00000000, |
2051 | }; | 2051 | }; |
2052 | 2052 | ||
2053 | const u32 b43_ntab_tdi40a0[] = { | 2053 | static const u32 b43_ntab_tdi40a0[] = { |
2054 | 0x0011A346, 0x00136CCF, 0x0014F5D9, 0x001641E2, | 2054 | 0x0011A346, 0x00136CCF, 0x0014F5D9, 0x001641E2, |
2055 | 0x0017CB6B, 0x00195475, 0x001B2383, 0x001CAD0C, | 2055 | 0x0017CB6B, 0x00195475, 0x001B2383, 0x001CAD0C, |
2056 | 0x001E7616, 0x0000821F, 0x00020BA8, 0x0003D4B2, | 2056 | 0x001E7616, 0x0000821F, 0x00020BA8, 0x0003D4B2, |
@@ -2081,7 +2081,7 @@ const u32 b43_ntab_tdi40a0[] = { | |||
2081 | 0x00000000, 0x00000000, | 2081 | 0x00000000, 0x00000000, |
2082 | }; | 2082 | }; |
2083 | 2083 | ||
2084 | const u32 b43_ntab_tdi40a1[] = { | 2084 | static const u32 b43_ntab_tdi40a1[] = { |
2085 | 0x001EDB36, 0x000129CA, 0x0002B353, 0x00047CDD, | 2085 | 0x001EDB36, 0x000129CA, 0x0002B353, 0x00047CDD, |
2086 | 0x0005C8E6, 0x000791EF, 0x00091BF9, 0x000AAA07, | 2086 | 0x0005C8E6, 0x000791EF, 0x00091BF9, 0x000AAA07, |
2087 | 0x000C3391, 0x000DFD1A, 0x00120923, 0x0013D22D, | 2087 | 0x000C3391, 0x000DFD1A, 0x00120923, 0x0013D22D, |
@@ -2112,7 +2112,7 @@ const u32 b43_ntab_tdi40a1[] = { | |||
2112 | 0x00000000, 0x00000000, | 2112 | 0x00000000, 0x00000000, |
2113 | }; | 2113 | }; |
2114 | 2114 | ||
2115 | const u32 b43_ntab_tdtrn[] = { | 2115 | static const u32 b43_ntab_tdtrn[] = { |
2116 | 0x061C061C, 0x0050EE68, 0xF592FE36, 0xFE5212F6, | 2116 | 0x061C061C, 0x0050EE68, 0xF592FE36, 0xFE5212F6, |
2117 | 0x00000C38, 0xFE5212F6, 0xF592FE36, 0x0050EE68, | 2117 | 0x00000C38, 0xFE5212F6, 0xF592FE36, 0x0050EE68, |
2118 | 0x061C061C, 0xEE680050, 0xFE36F592, 0x12F6FE52, | 2118 | 0x061C061C, 0xEE680050, 0xFE36F592, 0x12F6FE52, |
@@ -2291,7 +2291,7 @@ const u32 b43_ntab_tdtrn[] = { | |||
2291 | 0xFA58FC00, 0x0B64FC7E, 0x0800F7B6, 0x00F006BE, | 2291 | 0xFA58FC00, 0x0B64FC7E, 0x0800F7B6, 0x00F006BE, |
2292 | }; | 2292 | }; |
2293 | 2293 | ||
2294 | const u32 b43_ntab_tmap[] = { | 2294 | static const u32 b43_ntab_tmap[] = { |
2295 | 0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888, | 2295 | 0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888, |
2296 | 0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8, | 2296 | 0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8, |
2297 | 0xF1111110, 0x11111111, 0x11F11111, 0x00000111, | 2297 | 0xF1111110, 0x11111111, 0x11F11111, 0x00000111, |
@@ -2406,6 +2406,544 @@ const u32 b43_ntab_tmap[] = { | |||
2406 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 2406 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
2407 | }; | 2407 | }; |
2408 | 2408 | ||
2409 | const u32 b43_ntab_tx_gain_rev0_1_2[] = { | ||
2410 | 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42, | ||
2411 | 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44, | ||
2412 | 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844, | ||
2413 | 0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44, | ||
2414 | 0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844, | ||
2415 | 0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644, | ||
2416 | 0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444, | ||
2417 | 0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44, | ||
2418 | 0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844, | ||
2419 | 0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44, | ||
2420 | 0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944, | ||
2421 | 0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744, | ||
2422 | 0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544, | ||
2423 | 0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44, | ||
2424 | 0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844, | ||
2425 | 0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44, | ||
2426 | 0x03902b42, 0x03902a44, 0x03902a42, 0x03902944, | ||
2427 | 0x03902942, 0x03902844, 0x03902842, 0x03902744, | ||
2428 | 0x03902742, 0x03902644, 0x03902642, 0x03902544, | ||
2429 | 0x03902542, 0x03802b44, 0x03802b42, 0x03802a44, | ||
2430 | 0x03802a42, 0x03802944, 0x03802942, 0x03802844, | ||
2431 | 0x03802842, 0x03802744, 0x03802742, 0x03802644, | ||
2432 | 0x03802642, 0x03802544, 0x03802542, 0x03802444, | ||
2433 | 0x03802442, 0x03802344, 0x03802342, 0x03802244, | ||
2434 | 0x03802242, 0x03802144, 0x03802142, 0x03802044, | ||
2435 | 0x03802042, 0x03801f44, 0x03801f42, 0x03801e44, | ||
2436 | 0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44, | ||
2437 | 0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44, | ||
2438 | 0x03801a42, 0x03801944, 0x03801942, 0x03801844, | ||
2439 | 0x03801842, 0x03801744, 0x03801742, 0x03801644, | ||
2440 | 0x03801642, 0x03801544, 0x03801542, 0x03801444, | ||
2441 | 0x03801442, 0x03801344, 0x03801342, 0x00002b00, | ||
2442 | }; | ||
2443 | |||
2444 | const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { | ||
2445 | 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e, | ||
2446 | 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037, | ||
2447 | 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e, | ||
2448 | 0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037, | ||
2449 | 0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e, | ||
2450 | 0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037, | ||
2451 | 0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e, | ||
2452 | 0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037, | ||
2453 | 0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e, | ||
2454 | 0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037, | ||
2455 | 0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e, | ||
2456 | 0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037, | ||
2457 | 0x19410044, 0x19410042, 0x19410040, 0x1941003e, | ||
2458 | 0x1941003c, 0x1941003b, 0x19410039, 0x19410037, | ||
2459 | 0x18410044, 0x18410042, 0x18410040, 0x1841003e, | ||
2460 | 0x1841003c, 0x1841003b, 0x18410039, 0x18410037, | ||
2461 | 0x17410044, 0x17410042, 0x17410040, 0x1741003e, | ||
2462 | 0x1741003c, 0x1741003b, 0x17410039, 0x17410037, | ||
2463 | 0x16410044, 0x16410042, 0x16410040, 0x1641003e, | ||
2464 | 0x1641003c, 0x1641003b, 0x16410039, 0x16410037, | ||
2465 | 0x15410044, 0x15410042, 0x15410040, 0x1541003e, | ||
2466 | 0x1541003c, 0x1541003b, 0x15410039, 0x15410037, | ||
2467 | 0x14410044, 0x14410042, 0x14410040, 0x1441003e, | ||
2468 | 0x1441003c, 0x1441003b, 0x14410039, 0x14410037, | ||
2469 | 0x13410044, 0x13410042, 0x13410040, 0x1341003e, | ||
2470 | 0x1341003c, 0x1341003b, 0x13410039, 0x13410037, | ||
2471 | 0x12410044, 0x12410042, 0x12410040, 0x1241003e, | ||
2472 | 0x1241003c, 0x1241003b, 0x12410039, 0x12410037, | ||
2473 | 0x11410044, 0x11410042, 0x11410040, 0x1141003e, | ||
2474 | 0x1141003c, 0x1141003b, 0x11410039, 0x11410037, | ||
2475 | 0x10410044, 0x10410042, 0x10410040, 0x1041003e, | ||
2476 | 0x1041003c, 0x1041003b, 0x10410039, 0x10410037, | ||
2477 | }; | ||
2478 | |||
2479 | const u32 b43_ntab_tx_gain_rev3_5ghz[] = { | ||
2480 | 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e, | ||
2481 | 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037, | ||
2482 | 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e, | ||
2483 | 0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037, | ||
2484 | 0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e, | ||
2485 | 0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037, | ||
2486 | 0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e, | ||
2487 | 0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037, | ||
2488 | 0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e, | ||
2489 | 0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037, | ||
2490 | 0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e, | ||
2491 | 0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037, | ||
2492 | 0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e, | ||
2493 | 0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037, | ||
2494 | 0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e, | ||
2495 | 0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037, | ||
2496 | 0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e, | ||
2497 | 0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037, | ||
2498 | 0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e, | ||
2499 | 0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037, | ||
2500 | 0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e, | ||
2501 | 0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037, | ||
2502 | 0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e, | ||
2503 | 0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037, | ||
2504 | 0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e, | ||
2505 | 0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037, | ||
2506 | 0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e, | ||
2507 | 0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037, | ||
2508 | 0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e, | ||
2509 | 0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037, | ||
2510 | 0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e, | ||
2511 | 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037, | ||
2512 | }; | ||
2513 | |||
2514 | const u32 b43_ntab_tx_gain_rev4_5ghz[] = { | ||
2515 | 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e, | ||
2516 | 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037, | ||
2517 | 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e, | ||
2518 | 0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037, | ||
2519 | 0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e, | ||
2520 | 0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037, | ||
2521 | 0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e, | ||
2522 | 0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037, | ||
2523 | 0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e, | ||
2524 | 0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037, | ||
2525 | 0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e, | ||
2526 | 0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037, | ||
2527 | 0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e, | ||
2528 | 0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037, | ||
2529 | 0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e, | ||
2530 | 0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037, | ||
2531 | 0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e, | ||
2532 | 0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037, | ||
2533 | 0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e, | ||
2534 | 0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037, | ||
2535 | 0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e, | ||
2536 | 0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037, | ||
2537 | 0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e, | ||
2538 | 0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038, | ||
2539 | 0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e, | ||
2540 | 0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037, | ||
2541 | 0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e, | ||
2542 | 0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037, | ||
2543 | 0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e, | ||
2544 | 0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037, | ||
2545 | 0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c, | ||
2546 | 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034, | ||
2547 | }; | ||
2548 | |||
2549 | const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { | ||
2550 | 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044, | ||
2551 | 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c, | ||
2552 | 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e, | ||
2553 | 0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a, | ||
2554 | 0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e, | ||
2555 | 0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a, | ||
2556 | 0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e, | ||
2557 | 0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037, | ||
2558 | 0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040, | ||
2559 | 0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a, | ||
2560 | 0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c, | ||
2561 | 0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038, | ||
2562 | 0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b, | ||
2563 | 0x09620039, 0x09620037, 0x09620035, 0x09620033, | ||
2564 | 0x08620044, 0x08620042, 0x08620040, 0x0862003e, | ||
2565 | 0x0862003c, 0x0862003b, 0x0862003a, 0x08620039, | ||
2566 | 0x07620043, 0x07620042, 0x07620040, 0x0762003f, | ||
2567 | 0x0762003d, 0x0762003b, 0x0762003a, 0x07620039, | ||
2568 | 0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b, | ||
2569 | 0x06620039, 0x06620037, 0x06620035, 0x06620033, | ||
2570 | 0x05620046, 0x05620044, 0x05620042, 0x05620040, | ||
2571 | 0x0562003e, 0x0562003c, 0x0562003b, 0x05620039, | ||
2572 | 0x04620044, 0x04620042, 0x04620040, 0x0462003e, | ||
2573 | 0x0462003c, 0x0462003b, 0x04620039, 0x04620038, | ||
2574 | 0x0362003c, 0x0362003b, 0x0362003a, 0x03620039, | ||
2575 | 0x03620038, 0x03620037, 0x03620035, 0x03620033, | ||
2576 | 0x0262004c, 0x0262004a, 0x02620048, 0x02620047, | ||
2577 | 0x02620046, 0x02620044, 0x02620043, 0x02620042, | ||
2578 | 0x0162004a, 0x01620048, 0x01620046, 0x01620044, | ||
2579 | 0x01620043, 0x01620042, 0x01620041, 0x01620040, | ||
2580 | 0x00620042, 0x00620040, 0x0062003e, 0x0062003c, | ||
2581 | 0x0062003b, 0x00620039, 0x00620037, 0x00620035, | ||
2582 | }; | ||
2583 | |||
2584 | const u32 txpwrctrl_tx_gain_ipa[] = { | ||
2585 | 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029, | ||
2586 | 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025, | ||
2587 | 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029, | ||
2588 | 0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025, | ||
2589 | 0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029, | ||
2590 | 0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025, | ||
2591 | 0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029, | ||
2592 | 0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025, | ||
2593 | 0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029, | ||
2594 | 0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025, | ||
2595 | 0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029, | ||
2596 | 0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025, | ||
2597 | 0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029, | ||
2598 | 0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025, | ||
2599 | 0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029, | ||
2600 | 0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025, | ||
2601 | 0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029, | ||
2602 | 0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025, | ||
2603 | 0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029, | ||
2604 | 0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025, | ||
2605 | 0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029, | ||
2606 | 0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025, | ||
2607 | 0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029, | ||
2608 | 0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025, | ||
2609 | 0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029, | ||
2610 | 0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025, | ||
2611 | 0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029, | ||
2612 | 0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025, | ||
2613 | 0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029, | ||
2614 | 0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025, | ||
2615 | 0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029, | ||
2616 | 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025, | ||
2617 | }; | ||
2618 | |||
2619 | const u32 txpwrctrl_tx_gain_ipa_rev5[] = { | ||
2620 | 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029, | ||
2621 | 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025, | ||
2622 | 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029, | ||
2623 | 0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025, | ||
2624 | 0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029, | ||
2625 | 0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025, | ||
2626 | 0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029, | ||
2627 | 0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025, | ||
2628 | 0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029, | ||
2629 | 0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025, | ||
2630 | 0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029, | ||
2631 | 0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025, | ||
2632 | 0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029, | ||
2633 | 0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025, | ||
2634 | 0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029, | ||
2635 | 0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025, | ||
2636 | 0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029, | ||
2637 | 0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025, | ||
2638 | 0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029, | ||
2639 | 0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025, | ||
2640 | 0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029, | ||
2641 | 0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025, | ||
2642 | 0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029, | ||
2643 | 0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025, | ||
2644 | 0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029, | ||
2645 | 0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025, | ||
2646 | 0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029, | ||
2647 | 0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025, | ||
2648 | 0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029, | ||
2649 | 0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025, | ||
2650 | 0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029, | ||
2651 | 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025, | ||
2652 | }; | ||
2653 | |||
2654 | const u32 txpwrctrl_tx_gain_ipa_rev6[] = { | ||
2655 | 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029, | ||
2656 | 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025, | ||
2657 | 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029, | ||
2658 | 0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025, | ||
2659 | 0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029, | ||
2660 | 0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025, | ||
2661 | 0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029, | ||
2662 | 0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025, | ||
2663 | 0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029, | ||
2664 | 0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025, | ||
2665 | 0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029, | ||
2666 | 0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025, | ||
2667 | 0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029, | ||
2668 | 0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025, | ||
2669 | 0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029, | ||
2670 | 0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025, | ||
2671 | 0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029, | ||
2672 | 0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025, | ||
2673 | 0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029, | ||
2674 | 0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025, | ||
2675 | 0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029, | ||
2676 | 0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025, | ||
2677 | 0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029, | ||
2678 | 0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025, | ||
2679 | 0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029, | ||
2680 | 0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025, | ||
2681 | 0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029, | ||
2682 | 0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025, | ||
2683 | 0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029, | ||
2684 | 0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025, | ||
2685 | 0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029, | ||
2686 | 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025, | ||
2687 | }; | ||
2688 | |||
2689 | const u32 txpwrctrl_tx_gain_ipa_5g[] = { | ||
2690 | 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031, | ||
2691 | 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b, | ||
2692 | 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027, | ||
2693 | 0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022, | ||
2694 | 0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025, | ||
2695 | 0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027, | ||
2696 | 0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023, | ||
2697 | 0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027, | ||
2698 | 0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022, | ||
2699 | 0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025, | ||
2700 | 0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021, | ||
2701 | 0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026, | ||
2702 | 0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022, | ||
2703 | 0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026, | ||
2704 | 0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022, | ||
2705 | 0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026, | ||
2706 | 0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022, | ||
2707 | 0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026, | ||
2708 | 0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022, | ||
2709 | 0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026, | ||
2710 | 0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021, | ||
2711 | 0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026, | ||
2712 | 0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029, | ||
2713 | 0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024, | ||
2714 | 0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027, | ||
2715 | 0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023, | ||
2716 | 0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026, | ||
2717 | 0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022, | ||
2718 | 0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025, | ||
2719 | 0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027, | ||
2720 | 0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022, | ||
2721 | 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f, | ||
2722 | }; | ||
2723 | |||
2724 | const u16 tbl_iqcal_gainparams[2][9][8] = { | ||
2725 | { | ||
2726 | { 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 }, | ||
2727 | { 0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69 }, | ||
2728 | { 0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68 }, | ||
2729 | { 0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67 }, | ||
2730 | { 0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66 }, | ||
2731 | { 0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65 }, | ||
2732 | { 0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65 }, | ||
2733 | { 0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65 }, | ||
2734 | { 0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65 } | ||
2735 | }, | ||
2736 | { | ||
2737 | { 0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79 }, | ||
2738 | { 0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79 }, | ||
2739 | { 0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79 }, | ||
2740 | { 0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78 }, | ||
2741 | { 0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78 }, | ||
2742 | { 0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78 }, | ||
2743 | { 0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78 }, | ||
2744 | { 0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78 }, | ||
2745 | { 0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78 } | ||
2746 | } | ||
2747 | }; | ||
2748 | |||
2749 | const struct nphy_txiqcal_ladder ladder_lo[] = { | ||
2750 | { 3, 0 }, | ||
2751 | { 4, 0 }, | ||
2752 | { 6, 0 }, | ||
2753 | { 9, 0 }, | ||
2754 | { 13, 0 }, | ||
2755 | { 18, 0 }, | ||
2756 | { 25, 0 }, | ||
2757 | { 25, 1 }, | ||
2758 | { 25, 2 }, | ||
2759 | { 25, 3 }, | ||
2760 | { 25, 4 }, | ||
2761 | { 25, 5 }, | ||
2762 | { 25, 6 }, | ||
2763 | { 25, 7 }, | ||
2764 | { 35, 7 }, | ||
2765 | { 50, 7 }, | ||
2766 | { 71, 7 }, | ||
2767 | { 100, 7 } | ||
2768 | }; | ||
2769 | |||
2770 | const struct nphy_txiqcal_ladder ladder_iq[] = { | ||
2771 | { 3, 0 }, | ||
2772 | { 4, 0 }, | ||
2773 | { 6, 0 }, | ||
2774 | { 9, 0 }, | ||
2775 | { 13, 0 }, | ||
2776 | { 18, 0 }, | ||
2777 | { 25, 0 }, | ||
2778 | { 35, 0 }, | ||
2779 | { 50, 0 }, | ||
2780 | { 71, 0 }, | ||
2781 | { 100, 0 }, | ||
2782 | { 100, 1 }, | ||
2783 | { 100, 2 }, | ||
2784 | { 100, 3 }, | ||
2785 | { 100, 4 }, | ||
2786 | { 100, 5 }, | ||
2787 | { 100, 6 }, | ||
2788 | { 100, 7 } | ||
2789 | }; | ||
2790 | |||
2791 | const u16 loscale[] = { | ||
2792 | 256, 256, 271, 271, | ||
2793 | 287, 256, 256, 271, | ||
2794 | 271, 287, 287, 304, | ||
2795 | 304, 256, 256, 271, | ||
2796 | 271, 287, 287, 304, | ||
2797 | 304, 322, 322, 341, | ||
2798 | 341, 362, 362, 383, | ||
2799 | 383, 256, 256, 271, | ||
2800 | 271, 287, 287, 304, | ||
2801 | 304, 322, 322, 256, | ||
2802 | 256, 271, 271, 287, | ||
2803 | 287, 304, 304, 322, | ||
2804 | 322, 341, 341, 362, | ||
2805 | 362, 256, 256, 271, | ||
2806 | 271, 287, 287, 304, | ||
2807 | 304, 322, 322, 256, | ||
2808 | 256, 271, 271, 287, | ||
2809 | 287, 304, 304, 322, | ||
2810 | 322, 341, 341, 362, | ||
2811 | 362, 256, 256, 271, | ||
2812 | 271, 287, 287, 304, | ||
2813 | 304, 322, 322, 341, | ||
2814 | 341, 362, 362, 383, | ||
2815 | 383, 406, 406, 430, | ||
2816 | 430, 455, 455, 482, | ||
2817 | 482, 511, 511, 541, | ||
2818 | 541, 573, 573, 607, | ||
2819 | 607, 643, 643, 681, | ||
2820 | 681, 722, 722, 764, | ||
2821 | 764, 810, 810, 858, | ||
2822 | 858, 908, 908, 962, | ||
2823 | 962, 1019, 1019, 256 | ||
2824 | }; | ||
2825 | |||
2826 | const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { | ||
2827 | 0x0200, 0x0300, 0x0400, 0x0700, | ||
2828 | 0x0900, 0x0c00, 0x1200, 0x1201, | ||
2829 | 0x1202, 0x1203, 0x1204, 0x1205, | ||
2830 | 0x1206, 0x1207, 0x1907, 0x2307, | ||
2831 | 0x3207, 0x4707 | ||
2832 | }; | ||
2833 | |||
2834 | const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { | ||
2835 | 0x0300, 0x0500, 0x0700, 0x0900, | ||
2836 | 0x0d00, 0x1100, 0x1900, 0x1901, | ||
2837 | 0x1902, 0x1903, 0x1904, 0x1905, | ||
2838 | 0x1906, 0x1907, 0x2407, 0x3207, | ||
2839 | 0x4607, 0x6407 | ||
2840 | }; | ||
2841 | |||
2842 | const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { | ||
2843 | 0x0100, 0x0200, 0x0400, 0x0700, | ||
2844 | 0x0900, 0x0c00, 0x1200, 0x1900, | ||
2845 | 0x2300, 0x3200, 0x4700, 0x4701, | ||
2846 | 0x4702, 0x4703, 0x4704, 0x4705, | ||
2847 | 0x4706, 0x4707 | ||
2848 | }; | ||
2849 | |||
2850 | const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { | ||
2851 | 0x0200, 0x0300, 0x0600, 0x0900, | ||
2852 | 0x0d00, 0x1100, 0x1900, 0x2400, | ||
2853 | 0x3200, 0x4600, 0x6400, 0x6401, | ||
2854 | 0x6402, 0x6403, 0x6404, 0x6405, | ||
2855 | 0x6406, 0x6407 | ||
2856 | }; | ||
2857 | |||
2858 | const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3] = { }; | ||
2859 | |||
2860 | const u16 tbl_tx_iqlo_cal_startcoefs[B43_NTAB_TX_IQLO_CAL_STARTCOEFS] = { }; | ||
2861 | |||
2862 | const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { | ||
2863 | 0x8423, 0x8323, 0x8073, 0x8256, | ||
2864 | 0x8045, 0x8223, 0x9423, 0x9323, | ||
2865 | 0x9073, 0x9256, 0x9045, 0x9223 | ||
2866 | }; | ||
2867 | |||
2868 | const u16 tbl_tx_iqlo_cal_cmds_recal[] = { | ||
2869 | 0x8101, 0x8253, 0x8053, 0x8234, | ||
2870 | 0x8034, 0x9101, 0x9253, 0x9053, | ||
2871 | 0x9234, 0x9034 | ||
2872 | }; | ||
2873 | |||
2874 | const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { | ||
2875 | 0x8123, 0x8264, 0x8086, 0x8245, | ||
2876 | 0x8056, 0x9123, 0x9264, 0x9086, | ||
2877 | 0x9245, 0x9056 | ||
2878 | }; | ||
2879 | |||
2880 | const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { | ||
2881 | 0x8434, 0x8334, 0x8084, 0x8267, | ||
2882 | 0x8056, 0x8234, 0x9434, 0x9334, | ||
2883 | 0x9084, 0x9267, 0x9056, 0x9234 | ||
2884 | }; | ||
2885 | |||
2886 | const s16 tbl_tx_filter_coef_rev4[7][15] = { | ||
2887 | { -377, 137, -407, 208, -1527, | ||
2888 | 956, 93, 186, 93, 230, | ||
2889 | -44, 230, 20, -191, 201 }, | ||
2890 | { -77, 20, -98, 49, -93, | ||
2891 | 60, 56, 111, 56, 26, | ||
2892 | -5, 26, 34, -32, 34 }, | ||
2893 | { -360, 164, -376, 164, -1533, | ||
2894 | 576, 308, -314, 308, 121, | ||
2895 | -73, 121, 91, 124, 91 }, | ||
2896 | { -295, 200, -363, 142, -1391, | ||
2897 | 826, 151, 301, 151, 151, | ||
2898 | 301, 151, 602, -752, 602 }, | ||
2899 | { -92, 58, -96, 49, -104, | ||
2900 | 44, 17, 35, 17, 12, | ||
2901 | 25, 12, 13, 27, 13 }, | ||
2902 | { -375, 136, -399, 209, -1479, | ||
2903 | 949, 130, 260, 130, 230, | ||
2904 | -44, 230, 201, -191, 201 }, | ||
2905 | { 0xed9, 0xc8, 0xe95, 0x8e, 0xa91, | ||
2906 | 0x33a, 0x97, 0x12d, 0x97, 0x97, | ||
2907 | 0x12d, 0x97, 0x25a, 0xd10, 0x25a } | ||
2908 | }; | ||
2909 | |||
2910 | /* addr0, addr1, bmask, shift */ | ||
2911 | const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[] = { | ||
2912 | { 0x78, 0x78, 0x0038, 3 }, /* for field == 0x0002 (fls == 2) */ | ||
2913 | { 0x7A, 0x7D, 0x0001, 0 }, /* for field == 0x0004 (fls == 3) */ | ||
2914 | { 0x7A, 0x7D, 0x0002, 1 }, /* for field == 0x0008 (fls == 4) */ | ||
2915 | { 0x7A, 0x7D, 0x0004, 2 }, /* for field == 0x0010 (fls == 5) */ | ||
2916 | { 0x7A, 0x7D, 0x0030, 4 }, /* for field == 0x0020 (fls == 6) */ | ||
2917 | { 0x7A, 0x7D, 0x00C0, 6 }, /* for field == 0x0040 (fls == 7) */ | ||
2918 | { 0x7A, 0x7D, 0x0100, 8 }, /* for field == 0x0080 (fls == 8) */ | ||
2919 | { 0x7A, 0x7D, 0x0200, 9 }, /* for field == 0x0100 (fls == 9) */ | ||
2920 | { 0x78, 0x78, 0x0004, 2 }, /* for field == 0x0200 (fls == 10) */ | ||
2921 | { 0x7B, 0x7E, 0x01FF, 0 }, /* for field == 0x0400 (fls == 11) */ | ||
2922 | { 0x7C, 0x7F, 0x01FF, 0 }, /* for field == 0x0800 (fls == 12) */ | ||
2923 | { 0x78, 0x78, 0x0100, 8 }, /* for field == 0x1000 (fls == 13) */ | ||
2924 | { 0x78, 0x78, 0x0200, 9 }, /* for field == 0x2000 (fls == 14) */ | ||
2925 | { 0x78, 0x78, 0xF000, 12 } /* for field == 0x4000 (fls == 15) */ | ||
2926 | }; | ||
2927 | |||
2928 | /* val_mask, val_shift, en_addr0, val_addr0, en_addr1, val_addr1 */ | ||
2929 | const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { | ||
2930 | { 0x8000, 15, 0xE5, 0xF9, 0xE6, 0xFB }, /* field == 0x0001 (fls 1) */ | ||
2931 | { 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */ | ||
2932 | { 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */ | ||
2933 | { 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */ | ||
2934 | { 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ | ||
2935 | { 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */ | ||
2936 | { 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */ | ||
2937 | { 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ | ||
2938 | { 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ | ||
2939 | { 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */ | ||
2940 | { 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */ | ||
2941 | { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */ | ||
2942 | { 0xFFFF, 0, 0xE7, 0x7B, 0xEC, 0x7E }, /* field == 0x1000 (fls 13) */ | ||
2943 | { 0xFFFF, 0, 0xE7, 0x7C, 0xEC, 0x7F }, /* field == 0x2000 (fls 14) */ | ||
2944 | { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ | ||
2945 | }; | ||
2946 | |||
2409 | static inline void assert_ntab_array_sizes(void) | 2947 | static inline void assert_ntab_array_sizes(void) |
2410 | { | 2948 | { |
2411 | #undef check | 2949 | #undef check |
@@ -2442,6 +2980,72 @@ static inline void assert_ntab_array_sizes(void) | |||
2442 | #undef check | 2980 | #undef check |
2443 | } | 2981 | } |
2444 | 2982 | ||
2983 | u32 b43_ntab_read(struct b43_wldev *dev, u32 offset) | ||
2984 | { | ||
2985 | u32 type, value; | ||
2986 | |||
2987 | type = offset & B43_NTAB_TYPEMASK; | ||
2988 | offset &= ~B43_NTAB_TYPEMASK; | ||
2989 | B43_WARN_ON(offset > 0xFFFF); | ||
2990 | |||
2991 | switch (type) { | ||
2992 | case B43_NTAB_8BIT: | ||
2993 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
2994 | value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF; | ||
2995 | break; | ||
2996 | case B43_NTAB_16BIT: | ||
2997 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
2998 | value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); | ||
2999 | break; | ||
3000 | case B43_NTAB_32BIT: | ||
3001 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
3002 | value = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI); | ||
3003 | value <<= 16; | ||
3004 | value |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO); | ||
3005 | break; | ||
3006 | default: | ||
3007 | B43_WARN_ON(1); | ||
3008 | value = 0; | ||
3009 | } | ||
3010 | |||
3011 | return value; | ||
3012 | } | ||
3013 | |||
3014 | void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset, | ||
3015 | unsigned int nr_elements, void *_data) | ||
3016 | { | ||
3017 | u32 type; | ||
3018 | u8 *data = _data; | ||
3019 | unsigned int i; | ||
3020 | |||
3021 | type = offset & B43_NTAB_TYPEMASK; | ||
3022 | offset &= ~B43_NTAB_TYPEMASK; | ||
3023 | B43_WARN_ON(offset > 0xFFFF); | ||
3024 | |||
3025 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
3026 | |||
3027 | for (i = 0; i < nr_elements; i++) { | ||
3028 | switch (type) { | ||
3029 | case B43_NTAB_8BIT: | ||
3030 | *data = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF; | ||
3031 | data++; | ||
3032 | break; | ||
3033 | case B43_NTAB_16BIT: | ||
3034 | *((u16 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); | ||
3035 | data += 2; | ||
3036 | break; | ||
3037 | case B43_NTAB_32BIT: | ||
3038 | *((u32 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI); | ||
3039 | *((u32 *)data) <<= 16; | ||
3040 | *((u32 *)data) |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO); | ||
3041 | data += 4; | ||
3042 | break; | ||
3043 | default: | ||
3044 | B43_WARN_ON(1); | ||
3045 | } | ||
3046 | } | ||
3047 | } | ||
3048 | |||
2445 | void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) | 3049 | void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) |
2446 | { | 3050 | { |
2447 | u32 type; | 3051 | u32 type; |
@@ -2474,3 +3078,91 @@ void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) | |||
2474 | /* Some compiletime assertions... */ | 3078 | /* Some compiletime assertions... */ |
2475 | assert_ntab_array_sizes(); | 3079 | assert_ntab_array_sizes(); |
2476 | } | 3080 | } |
3081 | |||
3082 | void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, | ||
3083 | unsigned int nr_elements, const void *_data) | ||
3084 | { | ||
3085 | u32 type, value; | ||
3086 | const u8 *data = _data; | ||
3087 | unsigned int i; | ||
3088 | |||
3089 | type = offset & B43_NTAB_TYPEMASK; | ||
3090 | offset &= ~B43_NTAB_TYPEMASK; | ||
3091 | B43_WARN_ON(offset > 0xFFFF); | ||
3092 | |||
3093 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
3094 | |||
3095 | for (i = 0; i < nr_elements; i++) { | ||
3096 | switch (type) { | ||
3097 | case B43_NTAB_8BIT: | ||
3098 | value = *data; | ||
3099 | data++; | ||
3100 | B43_WARN_ON(value & ~0xFF); | ||
3101 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value); | ||
3102 | break; | ||
3103 | case B43_NTAB_16BIT: | ||
3104 | value = *((u16 *)data); | ||
3105 | data += 2; | ||
3106 | B43_WARN_ON(value & ~0xFFFF); | ||
3107 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value); | ||
3108 | break; | ||
3109 | case B43_NTAB_32BIT: | ||
3110 | value = *((u32 *)data); | ||
3111 | data += 4; | ||
3112 | b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, value >> 16); | ||
3113 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
3114 | value & 0xFFFF); | ||
3115 | break; | ||
3116 | default: | ||
3117 | B43_WARN_ON(1); | ||
3118 | } | ||
3119 | } | ||
3120 | } | ||
3121 | |||
3122 | #define ntab_upload(dev, offset, data) do { \ | ||
3123 | unsigned int i; \ | ||
3124 | for (i = 0; i < (offset##_SIZE); i++) \ | ||
3125 | b43_ntab_write(dev, (offset) + i, (data)[i]); \ | ||
3126 | } while (0) | ||
3127 | |||
3128 | void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) | ||
3129 | { | ||
3130 | /* Static tables */ | ||
3131 | ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct); | ||
3132 | ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup); | ||
3133 | ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap); | ||
3134 | ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn); | ||
3135 | ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel); | ||
3136 | ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot); | ||
3137 | ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt); | ||
3138 | ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0); | ||
3139 | ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1); | ||
3140 | ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0); | ||
3141 | ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1); | ||
3142 | ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi); | ||
3143 | ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest); | ||
3144 | ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs); | ||
3145 | |||
3146 | /* Volatile tables */ | ||
3147 | ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10); | ||
3148 | ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11); | ||
3149 | ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0); | ||
3150 | ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1); | ||
3151 | ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0); | ||
3152 | ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1); | ||
3153 | ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0); | ||
3154 | ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1); | ||
3155 | ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0); | ||
3156 | ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1); | ||
3157 | ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0); | ||
3158 | ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1); | ||
3159 | } | ||
3160 | |||
3161 | void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev) | ||
3162 | { | ||
3163 | /* Static tables */ | ||
3164 | /* TODO */ | ||
3165 | |||
3166 | /* Volatile tables */ | ||
3167 | /* TODO */ | ||
3168 | } | ||
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 4d498b053ec7..9c1c6ecd3672 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h | |||
@@ -46,6 +46,27 @@ struct b43_nphy_channeltab_entry { | |||
46 | 46 | ||
47 | struct b43_wldev; | 47 | struct b43_wldev; |
48 | 48 | ||
49 | struct nphy_txiqcal_ladder { | ||
50 | u8 percent; | ||
51 | u8 g_env; | ||
52 | }; | ||
53 | |||
54 | struct nphy_rf_control_override_rev2 { | ||
55 | u8 addr0; | ||
56 | u8 addr1; | ||
57 | u16 bmask; | ||
58 | u8 shift; | ||
59 | }; | ||
60 | |||
61 | struct nphy_rf_control_override_rev3 { | ||
62 | u16 val_mask; | ||
63 | u8 val_shift; | ||
64 | u8 en_addr0; | ||
65 | u8 val_addr0; | ||
66 | u8 en_addr1; | ||
67 | u8 val_addr1; | ||
68 | }; | ||
69 | |||
49 | /* Upload the default register value table. | 70 | /* Upload the default register value table. |
50 | * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz | 71 | * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz |
51 | * table is uploaded. If "ignore_uploadflag" is true, we upload any value | 72 | * table is uploaded. If "ignore_uploadflag" is true, we upload any value |
@@ -126,34 +147,57 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel); | |||
126 | #define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */ | 147 | #define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */ |
127 | #define B43_NTAB_C1_LOFEEDTH_SIZE 128 | 148 | #define B43_NTAB_C1_LOFEEDTH_SIZE 128 |
128 | 149 | ||
150 | #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18 | ||
151 | #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18 | ||
152 | #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18 | ||
153 | #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_20_SIZE 18 | ||
154 | #define B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3 11 | ||
155 | #define B43_NTAB_TX_IQLO_CAL_STARTCOEFS 9 | ||
156 | #define B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3 12 | ||
157 | #define B43_NTAB_TX_IQLO_CAL_CMDS_RECAL 10 | ||
158 | #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10 | ||
159 | #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12 | ||
160 | |||
161 | u32 b43_ntab_read(struct b43_wldev *dev, u32 offset); | ||
162 | void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset, | ||
163 | unsigned int nr_elements, void *_data); | ||
129 | void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); | 164 | void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); |
130 | 165 | void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, | |
131 | extern const u8 b43_ntab_adjustpower0[]; | 166 | unsigned int nr_elements, const void *_data); |
132 | extern const u8 b43_ntab_adjustpower1[]; | 167 | |
133 | extern const u16 b43_ntab_bdi[]; | 168 | void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); |
134 | extern const u32 b43_ntab_channelest[]; | 169 | void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); |
135 | extern const u8 b43_ntab_estimatepowerlt0[]; | 170 | |
136 | extern const u8 b43_ntab_estimatepowerlt1[]; | 171 | extern const u32 b43_ntab_tx_gain_rev0_1_2[]; |
137 | extern const u8 b43_ntab_framelookup[]; | 172 | extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[]; |
138 | extern const u32 b43_ntab_framestruct[]; | 173 | extern const u32 b43_ntab_tx_gain_rev3_5ghz[]; |
139 | extern const u32 b43_ntab_gainctl0[]; | 174 | extern const u32 b43_ntab_tx_gain_rev4_5ghz[]; |
140 | extern const u32 b43_ntab_gainctl1[]; | 175 | extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[]; |
141 | extern const u32 b43_ntab_intlevel[]; | 176 | |
142 | extern const u32 b43_ntab_iqlt0[]; | 177 | extern const u32 txpwrctrl_tx_gain_ipa[]; |
143 | extern const u32 b43_ntab_iqlt1[]; | 178 | extern const u32 txpwrctrl_tx_gain_ipa_rev5[]; |
144 | extern const u16 b43_ntab_loftlt0[]; | 179 | extern const u32 txpwrctrl_tx_gain_ipa_rev6[]; |
145 | extern const u16 b43_ntab_loftlt1[]; | 180 | extern const u32 txpwrctrl_tx_gain_ipa_5g[]; |
146 | extern const u8 b43_ntab_mcs[]; | 181 | extern const u16 tbl_iqcal_gainparams[2][9][8]; |
147 | extern const u32 b43_ntab_noisevar10[]; | 182 | extern const struct nphy_txiqcal_ladder ladder_lo[]; |
148 | extern const u32 b43_ntab_noisevar11[]; | 183 | extern const struct nphy_txiqcal_ladder ladder_iq[]; |
149 | extern const u16 b43_ntab_pilot[]; | 184 | extern const u16 loscale[]; |
150 | extern const u32 b43_ntab_pilotlt[]; | 185 | |
151 | extern const u32 b43_ntab_tdi20a0[]; | 186 | extern const u16 tbl_tx_iqlo_cal_loft_ladder_40[]; |
152 | extern const u32 b43_ntab_tdi20a1[]; | 187 | extern const u16 tbl_tx_iqlo_cal_loft_ladder_20[]; |
153 | extern const u32 b43_ntab_tdi40a0[]; | 188 | extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[]; |
154 | extern const u32 b43_ntab_tdi40a1[]; | 189 | extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[]; |
155 | extern const u32 b43_ntab_tdtrn[]; | 190 | extern const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[]; |
156 | extern const u32 b43_ntab_tmap[]; | 191 | extern const u16 tbl_tx_iqlo_cal_startcoefs[]; |
157 | 192 | extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[]; | |
193 | extern const u16 tbl_tx_iqlo_cal_cmds_recal[]; | ||
194 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[]; | ||
195 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[]; | ||
196 | extern const s16 tbl_tx_filter_coef_rev4[7][15]; | ||
197 | |||
198 | extern const struct nphy_rf_control_override_rev2 | ||
199 | tbl_rf_control_override_rev2[]; | ||
200 | extern const struct nphy_rf_control_override_rev3 | ||
201 | tbl_rf_control_override_rev3[]; | ||
158 | 202 | ||
159 | #endif /* B43_TABLES_NPHY_H_ */ | 203 | #endif /* B43_TABLES_NPHY_H_ */ |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index f4e9695ec186..eda06529ef5f 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "b43.h" | 30 | #include "xmit.h" |
31 | #include "phy_common.h" | 31 | #include "phy_common.h" |
32 | #include "dma.h" | 32 | #include "dma.h" |
33 | #include "pio.h" | 33 | #include "pio.h" |
@@ -621,7 +621,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
621 | (phystat0 & B43_RX_PHYST0_OFDM), | 621 | (phystat0 & B43_RX_PHYST0_OFDM), |
622 | (phystat0 & B43_RX_PHYST0_GAINCTL), | 622 | (phystat0 & B43_RX_PHYST0_GAINCTL), |
623 | (phystat3 & B43_RX_PHYST3_TRSTATE)); | 623 | (phystat3 & B43_RX_PHYST3_TRSTATE)); |
624 | status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI; | ||
625 | } | 624 | } |
626 | 625 | ||
627 | if (phystat0 & B43_RX_PHYST0_OFDM) | 626 | if (phystat0 & B43_RX_PHYST0_OFDM) |
@@ -690,10 +689,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
690 | } | 689 | } |
691 | 690 | ||
692 | memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); | 691 | memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); |
693 | 692 | ieee80211_rx_ni(dev->wl->hw, skb); | |
694 | local_bh_disable(); | ||
695 | ieee80211_rx(dev->wl->hw, skb); | ||
696 | local_bh_enable(); | ||
697 | 693 | ||
698 | #if B43_DEBUG | 694 | #if B43_DEBUG |
699 | dev->rx_count++; | 695 | dev->rx_count++; |
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 3530de871873..d23ff9fe0c9e 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h | |||
@@ -2,6 +2,8 @@ | |||
2 | #define B43_XMIT_H_ | 2 | #define B43_XMIT_H_ |
3 | 3 | ||
4 | #include "main.h" | 4 | #include "main.h" |
5 | #include <net/mac80211.h> | ||
6 | |||
5 | 7 | ||
6 | #define _b43_declare_plcp_hdr(size) \ | 8 | #define _b43_declare_plcp_hdr(size) \ |
7 | struct b43_plcp_hdr##size { \ | 9 | struct b43_plcp_hdr##size { \ |
@@ -332,4 +334,21 @@ static inline u8 b43_kidx_to_raw(struct b43_wldev *dev, u8 firmware_kidx) | |||
332 | return raw_kidx; | 334 | return raw_kidx; |
333 | } | 335 | } |
334 | 336 | ||
337 | /* struct b43_private_tx_info - TX info private to b43. | ||
338 | * The structure is placed in (struct ieee80211_tx_info *)->rate_driver_data | ||
339 | * | ||
340 | * @bouncebuffer: DMA Bouncebuffer (if used) | ||
341 | */ | ||
342 | struct b43_private_tx_info { | ||
343 | void *bouncebuffer; | ||
344 | }; | ||
345 | |||
346 | static inline struct b43_private_tx_info * | ||
347 | b43_get_priv_tx_info(struct ieee80211_tx_info *info) | ||
348 | { | ||
349 | BUILD_BUG_ON(sizeof(struct b43_private_tx_info) > | ||
350 | sizeof(info->rate_driver_data)); | ||
351 | return (struct b43_private_tx_info *)info->rate_driver_data; | ||
352 | } | ||
353 | |||
335 | #endif /* B43_XMIT_H_ */ | 354 | #endif /* B43_XMIT_H_ */ |