aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/b43
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/Kconfig8
-rw-r--r--drivers/net/wireless/b43/Makefile2
-rw-r--r--drivers/net/wireless/b43/b43.h39
-rw-r--r--drivers/net/wireless/b43/dma.c135
-rw-r--r--drivers/net/wireless/b43/dma.h11
-rw-r--r--drivers/net/wireless/b43/leds.c1
-rw-r--r--drivers/net/wireless/b43/lo.c1
-rw-r--r--drivers/net/wireless/b43/main.c119
-rw-r--r--drivers/net/wireless/b43/pcmcia.c27
-rw-r--r--drivers/net/wireless/b43/phy_a.c2
-rw-r--r--drivers/net/wireless/b43/phy_common.c45
-rw-r--r--drivers/net/wireless/b43/phy_common.h10
-rw-r--r--drivers/net/wireless/b43/phy_g.c1
-rw-r--r--drivers/net/wireless/b43/phy_lp.c733
-rw-r--r--drivers/net/wireless/b43/phy_lp.h11
-rw-r--r--drivers/net/wireless/b43/phy_n.c3036
-rw-r--r--drivers/net/wireless/b43/phy_n.h98
-rw-r--r--drivers/net/wireless/b43/pio.c103
-rw-r--r--drivers/net/wireless/b43/pio.h45
-rw-r--r--drivers/net/wireless/b43/rfkill.c10
-rw-r--r--drivers/net/wireless/b43/sdio.c1
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c744
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h100
-rw-r--r--drivers/net/wireless/b43/xmit.c8
-rw-r--r--drivers/net/wireless/b43/xmit.h19
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 @@
1config B43 1config 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.
83config B43_PIO 83config 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
12b43-y += lo.o 12b43-y += lo.o
13b43-y += wa.o 13b43-y += wa.o
14b43-y += dma.o 14b43-y += dma.o
15b43-$(CONFIG_B43_PIO) += pio.o 15b43-y += pio.o
16b43-y += rfkill.o 16b43-y += rfkill.o
17b43-$(CONFIG_B43_LEDS) += leds.o 17b43-$(CONFIG_B43_LEDS) += leds.o
18b43-$(CONFIG_B43_PCMCIA) += pcmcia.o 18b43-$(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. */
759struct b43_wl { 761struct 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
843static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw) 839static 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
889static inline bool b43_using_pio_transfers(struct b43_wldev *dev) 885static 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 */
906void b43info(struct b43_wl *wl, const char *fmt, ...) 897void 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
1159static int dma_tx_fragment(struct b43_dmaring *ring, 1164static 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
1259out_free_bounce:
1260 dev_kfree_skb_any(skb);
1261out_unmap_hdr: 1257out_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
1470void 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
1486static void dma_rx(struct b43_dmaring *ring, int *slot) 1503static 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
1624static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type, 1640static 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
169struct sk_buff; 173struct sk_buff;
170struct b43_private; 174struct 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);
274void b43_dma_tx_suspend(struct b43_wldev *dev); 276void b43_dma_tx_suspend(struct b43_wldev *dev);
275void b43_dma_tx_resume(struct b43_wldev *dev); 277void b43_dma_tx_resume(struct b43_wldev *dev);
276 278
277void b43_dma_get_tx_stats(struct b43_wldev *dev,
278 struct ieee80211_tx_queue_stats *stats);
279
280int b43_dma_tx(struct b43_wldev *dev, 279int b43_dma_tx(struct b43_wldev *dev,
281 struct sk_buff *skb); 280 struct sk_buff *skb);
282void b43_dma_handle_txstatus(struct b43_wldev *dev, 281void 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
39static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo, 40static 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");
67MODULE_LICENSE("GPL"); 68MODULE_LICENSE("GPL");
68 69
69MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); 70MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID);
70 71MODULE_FIRMWARE("b43/ucode11.fw");
72MODULE_FIRMWARE("b43/ucode13.fw");
73MODULE_FIRMWARE("b43/ucode14.fw");
74MODULE_FIRMWARE("b43/ucode15.fw");
75MODULE_FIRMWARE("b43/ucode5.fw");
76MODULE_FIRMWARE("b43/ucode9.fw");
71 77
72static int modparam_bad_frames_preempt; 78static int modparam_bad_frames_preempt;
73module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); 79module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
@@ -102,6 +108,9 @@ int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
102module_param_named(verbose, b43_modparam_verbose, int, 0644); 108module_param_named(verbose, b43_modparam_verbose, int, 0644);
103MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); 109MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
104 110
111int b43_modparam_pio = B43_PIO_DEFAULT;
112module_param_named(pio, b43_modparam_pio, int, 0644);
113MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
105 114
106static const struct ssb_device_id b43_ssb_tbl[] = { 115static 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)
628static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) 638static 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
637static void b43_short_slot_timing_enable(struct b43_wldev *dev) 654static 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
837static void b43_op_update_tkip_key(struct ieee80211_hw *hw, 854static 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))
859out_unlock: 878 return;
860 mutex_unlock(&wl->mutex); 879 keymac_write(dev, index, sta->addr);
861} 880}
862 881
863static void do_key_write(struct b43_wldev *dev, 882static 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 */
2960static void b43_periodic_work_handler(struct work_struct *work) 2983static 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
3338static 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
3359static int b43_op_get_stats(struct ieee80211_hw *hw, 3361static 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
4376out: 4383out:
@@ -4385,7 +4392,7 @@ err_busdown:
4385} 4392}
4386 4393
4387static int b43_op_add_interface(struct ieee80211_hw *hw, 4394static 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
4427static void b43_op_remove_interface(struct ieee80211_hw *hw, 4434static 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 */
426struct 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
6struct b43_wldev; 6struct b43_wldev;
7 7
8/* Complex number using 2 32-bit signed integers */
9struct 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 */
419void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); 428void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
420 429
430struct 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
38static const s8 b43_tssi2dbm_g_table[] = { 39static 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 */
82static void lpphy_read_band_sprom(struct b43_wldev *dev) 86static 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
764static 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
754static void lpphy_disable_crs(struct b43_wldev *dev, bool user) 771static 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
791struct lpphy_tx_gains { u16 gm, pga, pad, dac; }; 807struct lpphy_tx_gains { u16 gm, pga, pad, dac; };
792 808
809static 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
825static 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
841static 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
852static 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
793static struct lpphy_tx_gains lpphy_get_tx_gains(struct b43_wldev *dev) 863static 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
892static u16 lpphy_get_pa_gain(struct b43_wldev *dev)
893{
894 return b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x7F;
895}
896
897static 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
822static void lpphy_set_tx_gains(struct b43_wldev *dev, 903static 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
853static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain) 931static 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
890static 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
906static 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
922static void lpphy_set_rx_gain(struct b43_wldev *dev, u32 gain) 968static 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
1360static 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
1378static 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
1315static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index) 1387static 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
1326static void lpphy_btcoex_override(struct b43_wldev *dev) 1429static 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
1332static void lpphy_pr41573_workaround(struct b43_wldev *dev) 1435static 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
1365static void lpphy_calibration(struct b43_wldev *dev) 1461/* This was previously called lpphy_japan_filter */
1462static 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
1386static void lpphy_set_tssi_mux(struct b43_wldev *dev, enum tssi_mux_mode mode) 1476static 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
1582static 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
1636struct lpphy_rx_iq_comp { u8 chan; s8 c1, c0; };
1637
1638static 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
1655static 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
1709static const struct lpphy_rx_iq_comp lpphy_rev2plus_iq_comp = {
1710 .chan = 0,
1711 .c1 = -64,
1712 .c0 = 0,
1713};
1714
1715static 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
1766out:
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
1772static 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?
1785static 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
1818static 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
1834static 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
1840static 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
1869static 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
1963static 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
1492static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg) 1996static 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
1536static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
1537 bool blocked)
1538{
1539 //TODO
1540}
1541
1542struct b206x_channel { 2040struct 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 */
2009static 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
2023static void lpphy_b2063_vco_calib(struct b43_wldev *dev) 2505static 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
2207static 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
2219static void b43_lpphy_op_adjust_txpower(struct b43_wldev *dev) 2689static 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
2711static void b43_lpphy_op_pwork_15sec(struct b43_wldev *dev)
2712{
2713 //TODO
2714}
2715
2241const struct b43_phy_operations b43_phyops_lp = { 2716const 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
896enum tssi_mux_mode { 903enum 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
34struct nphy_txgains {
35 u16 txgm[2];
36 u16 pga[2];
37 u16 pad[2];
38 u16 ipa[2];
39};
40
41struct 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
50struct 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
59enum 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
68static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
69 u8 *events, u8 *delays, u8 length);
70static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
71 enum b43_nphy_rf_sequence seq);
72static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
73 u16 value, u8 core, bool off);
74static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
75 u16 value, u8 core);
32 76
33void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 77void 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. */
207static void b43_nphy_tables_init(struct b43_wldev *dev) 248static 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); 257static 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
240static void b43_nphy_workarounds(struct b43_wldev *dev) 290/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
291static 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 */
313static 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 */
329static 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 */
343static 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 */
357static 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 */
385static 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 */
424static 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 */
441static 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 */
464static 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 */
522static 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 */
621static 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 */
637static 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 */
644static 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 */
651static 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 */
672static 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); 695static 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); 722static 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 */
783static 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, 911static 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
344static void b43_nphy_reset_cca(struct b43_wldev *dev) 1021/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */
1022static 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 */
1049static 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
358enum b43_nphy_rf_sequence { 1092/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
359 B43_RFSEQ_RX2TX, 1093static 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 */
1156static 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 */
1167static 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 */
1233static 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 */
367static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, 1258static 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");
391ok: 1283ok:
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 */
1288static 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 */
1364static 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
396static void b43_nphy_bphy_init(struct b43_wldev *dev) 1461static 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 */
415static void b43_nphy_rssi_cal(struct b43_wldev *dev, u8 type) 1480static 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
1540static 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
1589static 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 */
1677static 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 */
1686static 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 */
1714static 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 */
1782static 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 */
1941static 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 */
1950static 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 */
1965static 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 */
2005static 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 */
2023static 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 */
2117static 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 */
2155static 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 */
2178static 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 */
2187static 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 */
2215static 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 */
2297static 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 */
2326static 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 */
2392static 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 */
2441static 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 */
2509static 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, &params[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 */
2733static 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 */
2766static 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
2946static 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 */
2953static 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 */
420int b43_phy_initn(struct b43_wldev *dev) 2966int 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
920struct b43_wldev; 925struct b43_wldev;
921 926
927struct b43_phy_n_iq_comp {
928 s16 a0;
929 s16 b0;
930 s16 a1;
931 s16 b1;
932};
933
934struct 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
942struct 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
952struct 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
922struct b43_phy_n { 965struct 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
36static u16 generate_cookie(struct b43_pio_txqueue *q, 37static 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
602void 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. */
619static bool pio_rx_frame(struct b43_pio_rxqueue *q) 609static 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
747rx_error: 746rx_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
60struct b43_pio_txpacket { 58struct 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);
162int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb); 157int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb);
163void b43_pio_handle_txstatus(struct b43_wldev *dev, 158void b43_pio_handle_txstatus(struct b43_wldev *dev,
164 const struct b43_txstatus *status); 159 const struct b43_txstatus *status);
165void b43_pio_get_tx_stats(struct b43_wldev *dev,
166 struct ieee80211_tx_queue_stats *stats);
167void b43_pio_rx(struct b43_pio_rxqueue *q); 160void b43_pio_rx(struct b43_pio_rxqueue *q);
168 161
169void b43_pio_tx_suspend(struct b43_wldev *dev); 162void b43_pio_tx_suspend(struct b43_wldev *dev);
170void b43_pio_tx_resume(struct b43_wldev *dev); 163void b43_pio_tx_resume(struct b43_wldev *dev);
171 164
172
173#else /* CONFIG_B43_PIO */
174
175
176static inline int b43_pio_init(struct b43_wldev *dev)
177{
178 return 0;
179}
180static inline void b43_pio_free(struct b43_wldev *dev)
181{
182}
183static inline void b43_pio_stop(struct b43_wldev *dev)
184{
185}
186static inline int b43_pio_tx(struct b43_wldev *dev,
187 struct sk_buff *skb)
188{
189 return 0;
190}
191static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
192 const struct b43_txstatus *status)
193{
194}
195static inline void b43_pio_get_tx_stats(struct b43_wldev *dev,
196 struct ieee80211_tx_queue_stats *stats)
197{
198}
199static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
200{
201}
202static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
203{
204}
205static 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
1339const u8 b43_ntab_adjustpower0[] = { 1339static 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
1358const u8 b43_ntab_adjustpower1[] = { 1358static 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
1377const u16 b43_ntab_bdi[] = { 1377static const u16 b43_ntab_bdi[] = {
1378 0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2, 1378 0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2,
1379}; 1379};
1380 1380
1381const u32 b43_ntab_channelest[] = { 1381static 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
1408const u8 b43_ntab_estimatepowerlt0[] = { 1408static 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
1419const u8 b43_ntab_estimatepowerlt1[] = { 1419static 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
1430const u8 b43_ntab_framelookup[] = { 1430static 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
1437const u32 b43_ntab_framestruct[] = { 1437static 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
1648const u32 b43_ntab_gainctl0[] = { 1648static 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
1683const u32 b43_ntab_gainctl1[] = { 1683static 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
1718const u32 b43_ntab_intlevel[] = { 1718static 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
1723const u32 b43_ntab_iqlt0[] = { 1723static 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
1758const u32 b43_ntab_iqlt1[] = { 1758static 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
1793const u16 b43_ntab_loftlt0[] = { 1793static 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
1818const u16 b43_ntab_loftlt1[] = { 1818static 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
1843const u8 b43_ntab_mcs[] = { 1843static 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
1862const u32 b43_ntab_noisevar10[] = { 1862static 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
1929const u32 b43_ntab_noisevar11[] = { 1929static 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
1996const u16 b43_ntab_pilot[] = { 1996static 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
2014const u32 b43_ntab_pilotlt[] = { 2014static 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
2019const u32 b43_ntab_tdi20a0[] = { 2019static 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
2036const u32 b43_ntab_tdi20a1[] = { 2036static 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
2053const u32 b43_ntab_tdi40a0[] = { 2053static 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
2084const u32 b43_ntab_tdi40a1[] = { 2084static 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
2115const u32 b43_ntab_tdtrn[] = { 2115static 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
2294const u32 b43_ntab_tmap[] = { 2294static 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
2409const 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
2444const 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
2479const 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
2514const 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
2549const 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
2584const 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
2619const 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
2654const 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
2689const 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
2724const 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
2749const 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
2770const 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
2791const 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
2826const 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
2834const 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
2842const 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
2850const 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
2858const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3] = { };
2859
2860const u16 tbl_tx_iqlo_cal_startcoefs[B43_NTAB_TX_IQLO_CAL_STARTCOEFS] = { };
2861
2862const 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
2868const u16 tbl_tx_iqlo_cal_cmds_recal[] = {
2869 0x8101, 0x8253, 0x8053, 0x8234,
2870 0x8034, 0x9101, 0x9253, 0x9053,
2871 0x9234, 0x9034
2872};
2873
2874const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
2875 0x8123, 0x8264, 0x8086, 0x8245,
2876 0x8056, 0x9123, 0x9264, 0x9086,
2877 0x9245, 0x9056
2878};
2879
2880const 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
2886const 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 */
2911const 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 */
2929const 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
2409static inline void assert_ntab_array_sizes(void) 2947static 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
2983u32 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
3014void 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
2445void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) 3049void 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
3082void 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
3128void 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
3161void 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
47struct b43_wldev; 47struct b43_wldev;
48 48
49struct nphy_txiqcal_ladder {
50 u8 percent;
51 u8 g_env;
52};
53
54struct nphy_rf_control_override_rev2 {
55 u8 addr0;
56 u8 addr1;
57 u16 bmask;
58 u8 shift;
59};
60
61struct 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
161u32 b43_ntab_read(struct b43_wldev *dev, u32 offset);
162void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
163 unsigned int nr_elements, void *_data);
129void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); 164void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value);
130 165void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
131extern const u8 b43_ntab_adjustpower0[]; 166 unsigned int nr_elements, const void *_data);
132extern const u8 b43_ntab_adjustpower1[]; 167
133extern const u16 b43_ntab_bdi[]; 168void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev);
134extern const u32 b43_ntab_channelest[]; 169void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
135extern const u8 b43_ntab_estimatepowerlt0[]; 170
136extern const u8 b43_ntab_estimatepowerlt1[]; 171extern const u32 b43_ntab_tx_gain_rev0_1_2[];
137extern const u8 b43_ntab_framelookup[]; 172extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[];
138extern const u32 b43_ntab_framestruct[]; 173extern const u32 b43_ntab_tx_gain_rev3_5ghz[];
139extern const u32 b43_ntab_gainctl0[]; 174extern const u32 b43_ntab_tx_gain_rev4_5ghz[];
140extern const u32 b43_ntab_gainctl1[]; 175extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[];
141extern const u32 b43_ntab_intlevel[]; 176
142extern const u32 b43_ntab_iqlt0[]; 177extern const u32 txpwrctrl_tx_gain_ipa[];
143extern const u32 b43_ntab_iqlt1[]; 178extern const u32 txpwrctrl_tx_gain_ipa_rev5[];
144extern const u16 b43_ntab_loftlt0[]; 179extern const u32 txpwrctrl_tx_gain_ipa_rev6[];
145extern const u16 b43_ntab_loftlt1[]; 180extern const u32 txpwrctrl_tx_gain_ipa_5g[];
146extern const u8 b43_ntab_mcs[]; 181extern const u16 tbl_iqcal_gainparams[2][9][8];
147extern const u32 b43_ntab_noisevar10[]; 182extern const struct nphy_txiqcal_ladder ladder_lo[];
148extern const u32 b43_ntab_noisevar11[]; 183extern const struct nphy_txiqcal_ladder ladder_iq[];
149extern const u16 b43_ntab_pilot[]; 184extern const u16 loscale[];
150extern const u32 b43_ntab_pilotlt[]; 185
151extern const u32 b43_ntab_tdi20a0[]; 186extern const u16 tbl_tx_iqlo_cal_loft_ladder_40[];
152extern const u32 b43_ntab_tdi20a1[]; 187extern const u16 tbl_tx_iqlo_cal_loft_ladder_20[];
153extern const u32 b43_ntab_tdi40a0[]; 188extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[];
154extern const u32 b43_ntab_tdi40a1[]; 189extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[];
155extern const u32 b43_ntab_tdtrn[]; 190extern const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[];
156extern const u32 b43_ntab_tmap[]; 191extern const u16 tbl_tx_iqlo_cal_startcoefs[];
157 192extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[];
193extern const u16 tbl_tx_iqlo_cal_cmds_recal[];
194extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[];
195extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[];
196extern const s16 tbl_tx_filter_coef_rev4[7][15];
197
198extern const struct nphy_rf_control_override_rev2
199 tbl_rf_control_override_rev2[];
200extern 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 */
342struct b43_private_tx_info {
343 void *bouncebuffer;
344};
345
346static inline struct b43_private_tx_info *
347b43_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_ */