aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-07-15 10:05:24 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-15 10:05:24 -0400
commit95a943c162d74b20d869917bdf5df11293c35b63 (patch)
treec69d5cb97a4d97b6062a276ecdfa8582535193af /drivers/net/wireless/b43
parentecae42d37045ec71831d0e0e493e00b0e0732edd (diff)
parent95acac61ba66c4abd40e038dae8c1ed2e176c7b1 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: net/bluetooth/l2cap_core.c
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/Kconfig14
-rw-r--r--drivers/net/wireless/b43/Makefile1
-rw-r--r--drivers/net/wireless/b43/b43.h1
-rw-r--r--drivers/net/wireless/b43/bus.c129
-rw-r--r--drivers/net/wireless/b43/bus.h8
-rw-r--r--drivers/net/wireless/b43/dma.c9
-rw-r--r--drivers/net/wireless/b43/main.c361
-rw-r--r--drivers/net/wireless/b43/phy_common.c6
-rw-r--r--drivers/net/wireless/b43/phy_common.h3
-rw-r--r--drivers/net/wireless/b43/phy_ht.c12
-rw-r--r--drivers/net/wireless/b43/phy_lcn.c52
-rw-r--r--drivers/net/wireless/b43/phy_lcn.h14
-rw-r--r--drivers/net/wireless/b43/phy_n.c62
-rw-r--r--drivers/net/wireless/b43/tables_phy_lcn.c34
-rw-r--r--drivers/net/wireless/b43/tables_phy_lcn.h6
-rw-r--r--drivers/net/wireless/b43/xmit.c3
16 files changed, 622 insertions, 93 deletions
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index d5add69aac8f..d2293dcc117f 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -90,6 +90,12 @@ config B43_SDIO
90 90
91#Data transfers to the device via PIO. We want it as a fallback even 91#Data transfers to the device via PIO. We want it as a fallback even
92# if we can do DMA. 92# if we can do DMA.
93config B43_BCMA_PIO
94 bool
95 depends on B43_BCMA
96 select BCMA_BLOCKIO
97 default y
98
93config B43_PIO 99config B43_PIO
94 bool 100 bool
95 depends on B43 101 depends on B43
@@ -125,6 +131,14 @@ config B43_PHY_HT
125 131
126 Say N, this is BROKEN and crashes driver. 132 Say N, this is BROKEN and crashes driver.
127 133
134config B43_PHY_LCN
135 bool "Support for LCN-PHY devices (BROKEN)"
136 depends on B43 && BROKEN
137 ---help---
138 Support for the LCN-PHY.
139
140 Say N, this is BROKEN and crashes driver.
141
128# This config option automatically enables b43 LEDS support, 142# This config option automatically enables b43 LEDS support,
129# if it's possible. 143# if it's possible.
130config B43_LEDS 144config B43_LEDS
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 1b25604be547..4648bbf76abc 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -13,6 +13,7 @@ b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o
13b43-$(CONFIG_B43_PHY_HT) += phy_ht.o 13b43-$(CONFIG_B43_PHY_HT) += phy_ht.o
14b43-$(CONFIG_B43_PHY_HT) += tables_phy_ht.o 14b43-$(CONFIG_B43_PHY_HT) += tables_phy_ht.o
15b43-$(CONFIG_B43_PHY_HT) += radio_2059.o 15b43-$(CONFIG_B43_PHY_HT) += radio_2059.o
16b43-$(CONFIG_B43_PHY_LCN) += phy_lcn.o tables_phy_lcn.o
16b43-y += sysfs.o 17b43-y += sysfs.o
17b43-y += xmit.o 18b43-y += xmit.o
18b43-y += lo.o 19b43-y += lo.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 666515e348b5..08a28270bbb3 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -726,7 +726,6 @@ enum {
726 726
727/* Data structure for one wireless device (802.11 core) */ 727/* Data structure for one wireless device (802.11 core) */
728struct b43_wldev { 728struct b43_wldev {
729 struct ssb_device *sdev; /* TODO: remove when b43_bus_dev is ready */
730 struct b43_bus_dev *dev; 729 struct b43_bus_dev *dev;
731 struct b43_wl *wl; 730 struct b43_wl *wl;
732 731
diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c
index 4200713eb597..a5e61a9fb539 100644
--- a/drivers/net/wireless/b43/bus.c
+++ b/drivers/net/wireless/b43/bus.c
@@ -23,6 +23,106 @@
23#include "b43.h" 23#include "b43.h"
24#include "bus.h" 24#include "bus.h"
25 25
26/* BCMA */
27#ifdef CONFIG_B43_BCMA
28static int b43_bus_bcma_bus_may_powerdown(struct b43_bus_dev *dev)
29{
30 return 0; /* bcma_bus_may_powerdown(dev->bdev->bus); */
31}
32static int b43_bus_bcma_bus_powerup(struct b43_bus_dev *dev,
33 bool dynamic_pctl)
34{
35 return 0; /* bcma_bus_powerup(dev->sdev->bus, dynamic_pctl); */
36}
37static int b43_bus_bcma_device_is_enabled(struct b43_bus_dev *dev)
38{
39 return bcma_core_is_enabled(dev->bdev);
40}
41static void b43_bus_bcma_device_enable(struct b43_bus_dev *dev,
42 u32 core_specific_flags)
43{
44 bcma_core_enable(dev->bdev, core_specific_flags);
45}
46static void b43_bus_bcma_device_disable(struct b43_bus_dev *dev,
47 u32 core_specific_flags)
48{
49 bcma_core_disable(dev->bdev, core_specific_flags);
50}
51static u16 b43_bus_bcma_read16(struct b43_bus_dev *dev, u16 offset)
52{
53 return bcma_read16(dev->bdev, offset);
54}
55static u32 b43_bus_bcma_read32(struct b43_bus_dev *dev, u16 offset)
56{
57 return bcma_read32(dev->bdev, offset);
58}
59static
60void b43_bus_bcma_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
61{
62 bcma_write16(dev->bdev, offset, value);
63}
64static
65void b43_bus_bcma_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
66{
67 bcma_write32(dev->bdev, offset, value);
68}
69static
70void b43_bus_bcma_block_read(struct b43_bus_dev *dev, void *buffer,
71 size_t count, u16 offset, u8 reg_width)
72{
73 bcma_block_read(dev->bdev, buffer, count, offset, reg_width);
74}
75static
76void b43_bus_bcma_block_write(struct b43_bus_dev *dev, const void *buffer,
77 size_t count, u16 offset, u8 reg_width)
78{
79 bcma_block_write(dev->bdev, buffer, count, offset, reg_width);
80}
81
82struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core)
83{
84 struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
85 if (!dev)
86 return NULL;
87
88 dev->bus_type = B43_BUS_BCMA;
89 dev->bdev = core;
90
91 dev->bus_may_powerdown = b43_bus_bcma_bus_may_powerdown;
92 dev->bus_powerup = b43_bus_bcma_bus_powerup;
93 dev->device_is_enabled = b43_bus_bcma_device_is_enabled;
94 dev->device_enable = b43_bus_bcma_device_enable;
95 dev->device_disable = b43_bus_bcma_device_disable;
96
97 dev->read16 = b43_bus_bcma_read16;
98 dev->read32 = b43_bus_bcma_read32;
99 dev->write16 = b43_bus_bcma_write16;
100 dev->write32 = b43_bus_bcma_write32;
101 dev->block_read = b43_bus_bcma_block_read;
102 dev->block_write = b43_bus_bcma_block_write;
103
104 dev->dev = &core->dev;
105 dev->dma_dev = core->dma_dev;
106 dev->irq = core->irq;
107
108 /*
109 dev->board_vendor = core->bus->boardinfo.vendor;
110 dev->board_type = core->bus->boardinfo.type;
111 dev->board_rev = core->bus->boardinfo.rev;
112 */
113
114 dev->chip_id = core->bus->chipinfo.id;
115 dev->chip_rev = core->bus->chipinfo.rev;
116 dev->chip_pkg = core->bus->chipinfo.pkg;
117
118 dev->bus_sprom = &core->bus->sprom;
119
120 dev->core_id = core->id.id;
121 dev->core_rev = core->id.rev;
122
123 return dev;
124}
125#endif /* CONFIG_B43_BCMA */
26 126
27/* SSB */ 127/* SSB */
28#ifdef CONFIG_B43_SSB 128#ifdef CONFIG_B43_SSB
@@ -125,3 +225,32 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev)
125 return dev; 225 return dev;
126} 226}
127#endif /* CONFIG_B43_SSB */ 227#endif /* CONFIG_B43_SSB */
228
229void *b43_bus_get_wldev(struct b43_bus_dev *dev)
230{
231 switch (dev->bus_type) {
232#ifdef CONFIG_B43_BCMA
233 case B43_BUS_BCMA:
234 return bcma_get_drvdata(dev->bdev);
235#endif
236#ifdef CONFIG_B43_SSB
237 case B43_BUS_SSB:
238 return ssb_get_drvdata(dev->sdev);
239#endif
240 }
241 return NULL;
242}
243
244void b43_bus_set_wldev(struct b43_bus_dev *dev, void *wldev)
245{
246 switch (dev->bus_type) {
247#ifdef CONFIG_B43_BCMA
248 case B43_BUS_BCMA:
249 bcma_set_drvdata(dev->bdev, wldev);
250#endif
251#ifdef CONFIG_B43_SSB
252 case B43_BUS_SSB:
253 ssb_set_drvdata(dev->sdev, wldev);
254#endif
255 }
256}
diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h
index 79a5ab4270c3..184c95659279 100644
--- a/drivers/net/wireless/b43/bus.h
+++ b/drivers/net/wireless/b43/bus.h
@@ -2,12 +2,16 @@
2#define B43_BUS_H_ 2#define B43_BUS_H_
3 3
4enum b43_bus_type { 4enum b43_bus_type {
5#ifdef CONFIG_B43_BCMA
6 B43_BUS_BCMA,
7#endif
5 B43_BUS_SSB, 8 B43_BUS_SSB,
6}; 9};
7 10
8struct b43_bus_dev { 11struct b43_bus_dev {
9 enum b43_bus_type bus_type; 12 enum b43_bus_type bus_type;
10 union { 13 union {
14 struct bcma_device *bdev;
11 struct ssb_device *sdev; 15 struct ssb_device *sdev;
12 }; 16 };
13 17
@@ -57,6 +61,10 @@ static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev)
57 dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); 61 dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO);
58} 62}
59 63
64struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core);
60struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); 65struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev);
61 66
67void *b43_bus_get_wldev(struct b43_bus_dev *dev);
68void b43_bus_set_wldev(struct b43_bus_dev *dev, void *data);
69
62#endif /* B43_BUS_H_ */ 70#endif /* B43_BUS_H_ */
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 7a09a467339c..ce572aebeffd 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1055,7 +1055,14 @@ int b43_dma_init(struct b43_wldev *dev)
1055 err = b43_dma_set_mask(dev, dmamask); 1055 err = b43_dma_set_mask(dev, dmamask);
1056 if (err) 1056 if (err)
1057 return err; 1057 return err;
1058 dma->translation = ssb_dma_translation(dev->sdev); 1058
1059 switch (dev->dev->bus_type) {
1060#ifdef CONFIG_B43_SSB
1061 case B43_BUS_SSB:
1062 dma->translation = ssb_dma_translation(dev->dev->sdev);
1063 break;
1064#endif
1065 }
1059 1066
1060 err = -ENOMEM; 1067 err = -ENOMEM;
1061 /* setup TX DMA channels. */ 1068 /* setup TX DMA channels. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index e9a01e3eede7..092dd9318869 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1155,6 +1155,21 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
1155 } 1155 }
1156} 1156}
1157 1157
1158#ifdef CONFIG_B43_BCMA
1159static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1160{
1161 u32 flags = 0;
1162
1163 if (gmode)
1164 flags = B43_BCMA_IOCTL_GMODE;
1165 flags |= B43_BCMA_IOCTL_PHY_CLKEN;
1166 flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ; /* Make 20 MHz def */
1167 b43_device_enable(dev, flags);
1168
1169 /* TODO: reset PHY */
1170}
1171#endif
1172
1158static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode) 1173static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1159{ 1174{
1160 struct ssb_device *sdev = dev->dev->sdev; 1175 struct ssb_device *sdev = dev->dev->sdev;
@@ -1187,7 +1202,18 @@ void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1187{ 1202{
1188 u32 macctl; 1203 u32 macctl;
1189 1204
1190 b43_ssb_wireless_core_reset(dev, gmode); 1205 switch (dev->dev->bus_type) {
1206#ifdef CONFIG_B43_BCMA
1207 case B43_BUS_BCMA:
1208 b43_bcma_wireless_core_reset(dev, gmode);
1209 break;
1210#endif
1211#ifdef CONFIG_B43_SSB
1212 case B43_BUS_SSB:
1213 b43_ssb_wireless_core_reset(dev, gmode);
1214 break;
1215#endif
1216 }
1191 1217
1192 /* Turn Analog ON, but only if we already know the PHY-type. 1218 /* Turn Analog ON, but only if we already know the PHY-type.
1193 * This protects against very early setup where we don't know the 1219 * This protects against very early setup where we don't know the
@@ -1938,7 +1964,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev)
1938 return IRQ_NONE; 1964 return IRQ_NONE;
1939 reason &= dev->irq_mask; 1965 reason &= dev->irq_mask;
1940 if (!reason) 1966 if (!reason)
1941 return IRQ_HANDLED; 1967 return IRQ_NONE;
1942 1968
1943 dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) 1969 dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)
1944 & 0x0001DC00; 1970 & 0x0001DC00;
@@ -2133,21 +2159,43 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
2133 u32 tmshigh; 2159 u32 tmshigh;
2134 int err; 2160 int err;
2135 2161
2162 /* Files for HT and LCN were found by trying one by one */
2163
2136 /* Get microcode */ 2164 /* Get microcode */
2137 if ((rev >= 5) && (rev <= 10)) 2165 if ((rev >= 5) && (rev <= 10)) {
2138 filename = "ucode5"; 2166 filename = "ucode5";
2139 else if ((rev >= 11) && (rev <= 12)) 2167 } else if ((rev >= 11) && (rev <= 12)) {
2140 filename = "ucode11"; 2168 filename = "ucode11";
2141 else if (rev == 13) 2169 } else if (rev == 13) {
2142 filename = "ucode13"; 2170 filename = "ucode13";
2143 else if (rev == 14) 2171 } else if (rev == 14) {
2144 filename = "ucode14"; 2172 filename = "ucode14";
2145 else if (rev == 15) 2173 } else if (rev == 15) {
2146 filename = "ucode15"; 2174 filename = "ucode15";
2147 else if ((rev >= 16) && (rev <= 20)) 2175 } else {
2148 filename = "ucode16_mimo"; 2176 switch (dev->phy.type) {
2149 else 2177 case B43_PHYTYPE_N:
2150 goto err_no_ucode; 2178 if (rev >= 16)
2179 filename = "ucode16_mimo";
2180 else
2181 goto err_no_ucode;
2182 break;
2183 case B43_PHYTYPE_HT:
2184 if (rev == 29)
2185 filename = "ucode29_mimo";
2186 else
2187 goto err_no_ucode;
2188 break;
2189 case B43_PHYTYPE_LCN:
2190 if (rev == 24)
2191 filename = "ucode24_mimo";
2192 else
2193 goto err_no_ucode;
2194 break;
2195 default:
2196 goto err_no_ucode;
2197 }
2198 }
2151 err = b43_do_request_fw(ctx, filename, &fw->ucode); 2199 err = b43_do_request_fw(ctx, filename, &fw->ucode);
2152 if (err) 2200 if (err)
2153 goto err_load; 2201 goto err_load;
@@ -2206,6 +2254,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
2206 else 2254 else
2207 goto err_no_initvals; 2255 goto err_no_initvals;
2208 break; 2256 break;
2257 case B43_PHYTYPE_HT:
2258 if (rev == 29)
2259 filename = "ht0initvals29";
2260 else
2261 goto err_no_initvals;
2262 break;
2263 case B43_PHYTYPE_LCN:
2264 if (rev == 24)
2265 filename = "lcn0initvals24";
2266 else
2267 goto err_no_initvals;
2268 break;
2209 default: 2269 default:
2210 goto err_no_initvals; 2270 goto err_no_initvals;
2211 } 2271 }
@@ -2253,6 +2313,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
2253 else 2313 else
2254 goto err_no_initvals; 2314 goto err_no_initvals;
2255 break; 2315 break;
2316 case B43_PHYTYPE_HT:
2317 if (rev == 29)
2318 filename = "ht0bsinitvals29";
2319 else
2320 goto err_no_initvals;
2321 break;
2322 case B43_PHYTYPE_LCN:
2323 if (rev == 24)
2324 filename = "lcn0bsinitvals24";
2325 else
2326 goto err_no_initvals;
2327 break;
2256 default: 2328 default:
2257 goto err_no_initvals; 2329 goto err_no_initvals;
2258 } 2330 }
@@ -2624,11 +2696,24 @@ static int b43_gpio_init(struct b43_wldev *dev)
2624 if (dev->dev->core_rev >= 2) 2696 if (dev->dev->core_rev >= 2)
2625 mask |= 0x0010; /* FIXME: This is redundant. */ 2697 mask |= 0x0010; /* FIXME: This is redundant. */
2626 2698
2627 gpiodev = b43_ssb_gpio_dev(dev); 2699 switch (dev->dev->bus_type) {
2628 if (gpiodev) 2700#ifdef CONFIG_B43_BCMA
2629 ssb_write32(gpiodev, B43_GPIO_CONTROL, 2701 case B43_BUS_BCMA:
2630 (ssb_read32(gpiodev, B43_GPIO_CONTROL) 2702 bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL,
2631 & mask) | set); 2703 (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc,
2704 BCMA_CC_GPIOCTL) & mask) | set);
2705 break;
2706#endif
2707#ifdef CONFIG_B43_SSB
2708 case B43_BUS_SSB:
2709 gpiodev = b43_ssb_gpio_dev(dev);
2710 if (gpiodev)
2711 ssb_write32(gpiodev, B43_GPIO_CONTROL,
2712 (ssb_read32(gpiodev, B43_GPIO_CONTROL)
2713 & mask) | set);
2714 break;
2715#endif
2716 }
2632 2717
2633 return 0; 2718 return 0;
2634} 2719}
@@ -2638,9 +2723,21 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)
2638{ 2723{
2639 struct ssb_device *gpiodev; 2724 struct ssb_device *gpiodev;
2640 2725
2641 gpiodev = b43_ssb_gpio_dev(dev); 2726 switch (dev->dev->bus_type) {
2642 if (gpiodev) 2727#ifdef CONFIG_B43_BCMA
2643 ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); 2728 case B43_BUS_BCMA:
2729 bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL,
2730 0);
2731 break;
2732#endif
2733#ifdef CONFIG_B43_SSB
2734 case B43_BUS_SSB:
2735 gpiodev = b43_ssb_gpio_dev(dev);
2736 if (gpiodev)
2737 ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
2738 break;
2739#endif
2740 }
2644} 2741}
2645 2742
2646/* http://bcm-specs.sipsolutions.net/EnableMac */ 2743/* http://bcm-specs.sipsolutions.net/EnableMac */
@@ -2712,12 +2809,30 @@ out:
2712/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ 2809/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
2713void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) 2810void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
2714{ 2811{
2715 u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); 2812 u32 tmp;
2716 if (on) 2813
2717 tmslow |= B43_TMSLOW_MACPHYCLKEN; 2814 switch (dev->dev->bus_type) {
2718 else 2815#ifdef CONFIG_B43_BCMA
2719 tmslow &= ~B43_TMSLOW_MACPHYCLKEN; 2816 case B43_BUS_BCMA:
2720 ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); 2817 tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL);
2818 if (on)
2819 tmp |= B43_BCMA_IOCTL_MACPHYCLKEN;
2820 else
2821 tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN;
2822 bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp);
2823 break;
2824#endif
2825#ifdef CONFIG_B43_SSB
2826 case B43_BUS_SSB:
2827 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
2828 if (on)
2829 tmp |= B43_TMSLOW_MACPHYCLKEN;
2830 else
2831 tmp &= ~B43_TMSLOW_MACPHYCLKEN;
2832 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
2833 break;
2834#endif
2835 }
2721} 2836}
2722 2837
2723static void b43_adjust_opmode(struct b43_wldev *dev) 2838static void b43_adjust_opmode(struct b43_wldev *dev)
@@ -2956,8 +3071,20 @@ static int b43_chip_init(struct b43_wldev *dev)
2956 3071
2957 b43_mac_phy_clock_set(dev, true); 3072 b43_mac_phy_clock_set(dev, true);
2958 3073
2959 b43_write16(dev, B43_MMIO_POWERUP_DELAY, 3074 switch (dev->dev->bus_type) {
2960 dev->sdev->bus->chipco.fast_pwrup_delay); 3075#ifdef CONFIG_B43_BCMA
3076 case B43_BUS_BCMA:
3077 /* FIXME: 0xE74 is quite common, but should be read from CC */
3078 b43_write16(dev, B43_MMIO_POWERUP_DELAY, 0xE74);
3079 break;
3080#endif
3081#ifdef CONFIG_B43_SSB
3082 case B43_BUS_SSB:
3083 b43_write16(dev, B43_MMIO_POWERUP_DELAY,
3084 dev->dev->sdev->bus->chipco.fast_pwrup_delay);
3085 break;
3086#endif
3087 }
2961 3088
2962 err = 0; 3089 err = 0;
2963 b43dbg(dev->wl, "Chip initialized\n"); 3090 b43dbg(dev->wl, "Chip initialized\n");
@@ -3473,21 +3600,33 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
3473 3600
3474static void b43_put_phy_into_reset(struct b43_wldev *dev) 3601static void b43_put_phy_into_reset(struct b43_wldev *dev)
3475{ 3602{
3476 struct ssb_device *sdev = dev->sdev; 3603 u32 tmp;
3477 u32 tmslow;
3478 3604
3479 tmslow = ssb_read32(sdev, SSB_TMSLOW); 3605 switch (dev->dev->bus_type) {
3480 tmslow &= ~B43_TMSLOW_GMODE; 3606#ifdef CONFIG_B43_BCMA
3481 tmslow |= B43_TMSLOW_PHYRESET; 3607 case B43_BUS_BCMA:
3482 tmslow |= SSB_TMSLOW_FGC; 3608 b43err(dev->wl,
3483 ssb_write32(sdev, SSB_TMSLOW, tmslow); 3609 "Putting PHY into reset not supported on BCMA\n");
3484 msleep(1); 3610 break;
3611#endif
3612#ifdef CONFIG_B43_SSB
3613 case B43_BUS_SSB:
3614 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
3615 tmp &= ~B43_TMSLOW_GMODE;
3616 tmp |= B43_TMSLOW_PHYRESET;
3617 tmp |= SSB_TMSLOW_FGC;
3618 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
3619 msleep(1);
3620
3621 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
3622 tmp &= ~SSB_TMSLOW_FGC;
3623 tmp |= B43_TMSLOW_PHYRESET;
3624 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
3625 msleep(1);
3485 3626
3486 tmslow = ssb_read32(sdev, SSB_TMSLOW); 3627 break;
3487 tmslow &= ~SSB_TMSLOW_FGC; 3628#endif
3488 tmslow |= B43_TMSLOW_PHYRESET; 3629 }
3489 ssb_write32(sdev, SSB_TMSLOW, tmslow);
3490 msleep(1);
3491} 3630}
3492 3631
3493static const char *band_to_string(enum ieee80211_band band) 3632static const char *band_to_string(enum ieee80211_band band)
@@ -4104,6 +4243,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4104 unsupported = 1; 4243 unsupported = 1;
4105 break; 4244 break;
4106#endif 4245#endif
4246#ifdef CONFIG_B43_PHY_LCN
4247 case B43_PHYTYPE_LCN:
4248 if (phy_rev > 1)
4249 unsupported = 1;
4250 break;
4251#endif
4107 default: 4252 default:
4108 unsupported = 1; 4253 unsupported = 1;
4109 } 4254 }
@@ -4117,22 +4262,42 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4117 analog_type, phy_type, phy_rev); 4262 analog_type, phy_type, phy_rev);
4118 4263
4119 /* Get RADIO versioning */ 4264 /* Get RADIO versioning */
4120 if (dev->dev->chip_id == 0x4317) { 4265 if (dev->dev->core_rev >= 24) {
4121 if (dev->dev->chip_rev == 0) 4266 u16 radio24[3];
4122 tmp = 0x3205017F; 4267
4123 else if (dev->dev->chip_rev == 1) 4268 for (tmp = 0; tmp < 3; tmp++) {
4124 tmp = 0x4205017F; 4269 b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
4125 else 4270 radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
4126 tmp = 0x5205017F; 4271 }
4272
4273 /* Broadcom uses "id" for our "ver" and has separated "ver" */
4274 /* radio_ver = (radio24[0] & 0xF0) >> 4; */
4275
4276 radio_manuf = 0x17F;
4277 radio_ver = (radio24[2] << 8) | radio24[1];
4278 radio_rev = (radio24[0] & 0xF);
4127 } else { 4279 } else {
4128 b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); 4280 if (dev->dev->chip_id == 0x4317) {
4129 tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); 4281 if (dev->dev->chip_rev == 0)
4130 b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); 4282 tmp = 0x3205017F;
4131 tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16; 4283 else if (dev->dev->chip_rev == 1)
4132 } 4284 tmp = 0x4205017F;
4133 radio_manuf = (tmp & 0x00000FFF); 4285 else
4134 radio_ver = (tmp & 0x0FFFF000) >> 12; 4286 tmp = 0x5205017F;
4135 radio_rev = (tmp & 0xF0000000) >> 28; 4287 } else {
4288 b43_write16(dev, B43_MMIO_RADIO_CONTROL,
4289 B43_RADIOCTL_ID);
4290 tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
4291 b43_write16(dev, B43_MMIO_RADIO_CONTROL,
4292 B43_RADIOCTL_ID);
4293 tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
4294 << 16;
4295 }
4296 radio_manuf = (tmp & 0x00000FFF);
4297 radio_ver = (tmp & 0x0FFFF000) >> 12;
4298 radio_rev = (tmp & 0xF0000000) >> 28;
4299 }
4300
4136 if (radio_manuf != 0x17F /* Broadcom */) 4301 if (radio_manuf != 0x17F /* Broadcom */)
4137 unsupported = 1; 4302 unsupported = 1;
4138 switch (phy_type) { 4303 switch (phy_type) {
@@ -4164,6 +4329,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4164 if (radio_ver != 0x2059) 4329 if (radio_ver != 0x2059)
4165 unsupported = 1; 4330 unsupported = 1;
4166 break; 4331 break;
4332 case B43_PHYTYPE_LCN:
4333 if (radio_ver != 0x2064)
4334 unsupported = 1;
4335 break;
4167 default: 4336 default:
4168 B43_WARN_ON(1); 4337 B43_WARN_ON(1);
4169 } 4338 }
@@ -4347,7 +4516,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4347/* Initialize a wireless core */ 4516/* Initialize a wireless core */
4348static int b43_wireless_core_init(struct b43_wldev *dev) 4517static int b43_wireless_core_init(struct b43_wldev *dev)
4349{ 4518{
4350 struct ssb_bus *bus = dev->sdev->bus;
4351 struct ssb_sprom *sprom = dev->dev->bus_sprom; 4519 struct ssb_sprom *sprom = dev->dev->bus_sprom;
4352 struct b43_phy *phy = &dev->phy; 4520 struct b43_phy *phy = &dev->phy;
4353 int err; 4521 int err;
@@ -4366,7 +4534,20 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4366 phy->ops->prepare_structs(dev); 4534 phy->ops->prepare_structs(dev);
4367 4535
4368 /* Enable IRQ routing to this device. */ 4536 /* Enable IRQ routing to this device. */
4369 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev); 4537 switch (dev->dev->bus_type) {
4538#ifdef CONFIG_B43_BCMA
4539 case B43_BUS_BCMA:
4540 bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci,
4541 dev->dev->bdev, true);
4542 break;
4543#endif
4544#ifdef CONFIG_B43_SSB
4545 case B43_BUS_SSB:
4546 ssb_pcicore_dev_irqvecs_enable(&dev->dev->sdev->bus->pcicore,
4547 dev->dev->sdev);
4548 break;
4549#endif
4550 }
4370 4551
4371 b43_imcfglo_timeouts_workaround(dev); 4552 b43_imcfglo_timeouts_workaround(dev);
4372 b43_bluetooth_coext_disable(dev); 4553 b43_bluetooth_coext_disable(dev);
@@ -4397,8 +4578,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4397 if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) 4578 if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
4398 hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ 4579 hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
4399#ifdef CONFIG_SSB_DRIVER_PCICORE 4580#ifdef CONFIG_SSB_DRIVER_PCICORE
4400 if ((bus->bustype == SSB_BUSTYPE_PCI) && 4581 if (dev->dev->bus_type == B43_BUS_SSB &&
4401 (bus->pcicore.dev->id.revision <= 10)) 4582 dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
4583 dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
4402 hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */ 4584 hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */
4403#endif 4585#endif
4404 hf &= ~B43_HF_SKCFPUP; 4586 hf &= ~B43_HF_SKCFPUP;
@@ -4764,8 +4946,7 @@ static void b43_wireless_core_detach(struct b43_wldev *dev)
4764static int b43_wireless_core_attach(struct b43_wldev *dev) 4946static int b43_wireless_core_attach(struct b43_wldev *dev)
4765{ 4947{
4766 struct b43_wl *wl = dev->wl; 4948 struct b43_wl *wl = dev->wl;
4767 struct ssb_bus *bus = dev->sdev->bus; 4949 struct pci_dev *pdev = NULL;
4768 struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
4769 int err; 4950 int err;
4770 bool have_2ghz_phy = 0, have_5ghz_phy = 0; 4951 bool have_2ghz_phy = 0, have_5ghz_phy = 0;
4771 4952
@@ -4776,20 +4957,38 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
4776 * that in core_init(), too. 4957 * that in core_init(), too.
4777 */ 4958 */
4778 4959
4960#ifdef CONFIG_B43_SSB
4961 if (dev->dev->bus_type == B43_BUS_SSB &&
4962 dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI)
4963 pdev = dev->dev->sdev->bus->host_pci;
4964#endif
4965
4779 err = b43_bus_powerup(dev, 0); 4966 err = b43_bus_powerup(dev, 0);
4780 if (err) { 4967 if (err) {
4781 b43err(wl, "Bus powerup failed\n"); 4968 b43err(wl, "Bus powerup failed\n");
4782 goto out; 4969 goto out;
4783 } 4970 }
4784 /* Get the PHY type. */
4785 if (dev->dev->core_rev >= 5) {
4786 u32 tmshigh;
4787 4971
4788 tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); 4972 /* Get the PHY type. */
4789 have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); 4973 switch (dev->dev->bus_type) {
4790 have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); 4974#ifdef CONFIG_B43_BCMA
4791 } else 4975 case B43_BUS_BCMA:
4792 B43_WARN_ON(1); 4976 /* FIXME */
4977 have_2ghz_phy = 1;
4978 have_5ghz_phy = 0;
4979 break;
4980#endif
4981#ifdef CONFIG_B43_SSB
4982 case B43_BUS_SSB:
4983 if (dev->dev->core_rev >= 5) {
4984 u32 tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
4985 have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY);
4986 have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY);
4987 } else
4988 B43_WARN_ON(1);
4989 break;
4990#endif
4991 }
4793 4992
4794 dev->phy.gmode = have_2ghz_phy; 4993 dev->phy.gmode = have_2ghz_phy;
4795 dev->phy.radio_on = 1; 4994 dev->phy.radio_on = 1;
@@ -4815,6 +5014,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
4815#endif 5014#endif
4816 case B43_PHYTYPE_G: 5015 case B43_PHYTYPE_G:
4817 case B43_PHYTYPE_N: 5016 case B43_PHYTYPE_N:
5017 case B43_PHYTYPE_HT:
5018 case B43_PHYTYPE_LCN:
4818 have_2ghz_phy = 1; 5019 have_2ghz_phy = 1;
4819 break; 5020 break;
4820 default: 5021 default:
@@ -4877,13 +5078,13 @@ static void b43_one_core_detach(struct b43_bus_dev *dev)
4877 /* Do not cancel ieee80211-workqueue based work here. 5078 /* Do not cancel ieee80211-workqueue based work here.
4878 * See comment in b43_remove(). */ 5079 * See comment in b43_remove(). */
4879 5080
4880 wldev = ssb_get_drvdata(dev->sdev); 5081 wldev = b43_bus_get_wldev(dev);
4881 wl = wldev->wl; 5082 wl = wldev->wl;
4882 b43_debugfs_remove_device(wldev); 5083 b43_debugfs_remove_device(wldev);
4883 b43_wireless_core_detach(wldev); 5084 b43_wireless_core_detach(wldev);
4884 list_del(&wldev->list); 5085 list_del(&wldev->list);
4885 wl->nr_devs--; 5086 wl->nr_devs--;
4886 ssb_set_drvdata(dev->sdev, NULL); 5087 b43_bus_set_wldev(dev, NULL);
4887 kfree(wldev); 5088 kfree(wldev);
4888} 5089}
4889 5090
@@ -4898,7 +5099,6 @@ static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)
4898 5099
4899 wldev->use_pio = b43_modparam_pio; 5100 wldev->use_pio = b43_modparam_pio;
4900 wldev->dev = dev; 5101 wldev->dev = dev;
4901 wldev->sdev = dev->sdev; /* TODO: Remove when not needed */
4902 wldev->wl = wl; 5102 wldev->wl = wl;
4903 b43_set_status(wldev, B43_STAT_UNINIT); 5103 b43_set_status(wldev, B43_STAT_UNINIT);
4904 wldev->bad_frames_preempt = modparam_bad_frames_preempt; 5104 wldev->bad_frames_preempt = modparam_bad_frames_preempt;
@@ -4910,7 +5110,7 @@ static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)
4910 5110
4911 list_add(&wldev->list, &wl->devlist); 5111 list_add(&wldev->list, &wl->devlist);
4912 wl->nr_devs++; 5112 wl->nr_devs++;
4913 ssb_set_drvdata(dev->sdev, wldev); 5113 b43_bus_set_wldev(dev, wldev);
4914 b43_debugfs_add_device(wldev); 5114 b43_debugfs_add_device(wldev);
4915 5115
4916 out: 5116 out:
@@ -4959,9 +5159,9 @@ static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl)
4959 ieee80211_free_hw(hw); 5159 ieee80211_free_hw(hw);
4960} 5160}
4961 5161
4962static struct b43_wl *b43_wireless_init(struct ssb_device *dev) 5162static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
4963{ 5163{
4964 struct ssb_sprom *sprom = &dev->bus->sprom; 5164 struct ssb_sprom *sprom = dev->bus_sprom;
4965 struct ieee80211_hw *hw; 5165 struct ieee80211_hw *hw;
4966 struct b43_wl *wl; 5166 struct b43_wl *wl;
4967 5167
@@ -5003,14 +5203,21 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev)
5003 skb_queue_head_init(&wl->tx_queue); 5203 skb_queue_head_init(&wl->tx_queue);
5004 5204
5005 b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", 5205 b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
5006 dev->bus->chip_id, dev->id.revision); 5206 dev->chip_id, dev->core_rev);
5007 return wl; 5207 return wl;
5008} 5208}
5009 5209
5010#ifdef CONFIG_B43_BCMA 5210#ifdef CONFIG_B43_BCMA
5011static int b43_bcma_probe(struct bcma_device *core) 5211static int b43_bcma_probe(struct bcma_device *core)
5012{ 5212{
5213 struct b43_bus_dev *dev;
5214
5215 dev = b43_bus_dev_bcma_init(core);
5216 if (!dev)
5217 return -ENODEV;
5218
5013 b43err(NULL, "BCMA is not supported yet!"); 5219 b43err(NULL, "BCMA is not supported yet!");
5220 kfree(dev);
5014 return -EOPNOTSUPP; 5221 return -EOPNOTSUPP;
5015} 5222}
5016 5223
@@ -5045,7 +5252,7 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
5045 /* Probing the first core. Must setup common struct b43_wl */ 5252 /* Probing the first core. Must setup common struct b43_wl */
5046 first = 1; 5253 first = 1;
5047 b43_sprom_fixup(sdev->bus); 5254 b43_sprom_fixup(sdev->bus);
5048 wl = b43_wireless_init(sdev); 5255 wl = b43_wireless_init(dev);
5049 if (IS_ERR(wl)) { 5256 if (IS_ERR(wl)) {
5050 err = PTR_ERR(wl); 5257 err = PTR_ERR(wl);
5051 goto out; 5258 goto out;
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 9705950f059a..101957512bcc 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -32,6 +32,7 @@
32#include "phy_n.h" 32#include "phy_n.h"
33#include "phy_lp.h" 33#include "phy_lp.h"
34#include "phy_ht.h" 34#include "phy_ht.h"
35#include "phy_lcn.h"
35#include "b43.h" 36#include "b43.h"
36#include "main.h" 37#include "main.h"
37 38
@@ -65,6 +66,11 @@ int b43_phy_allocate(struct b43_wldev *dev)
65 phy->ops = &b43_phyops_ht; 66 phy->ops = &b43_phyops_ht;
66#endif 67#endif
67 break; 68 break;
69 case B43_PHYTYPE_LCN:
70#ifdef CONFIG_B43_PHY_LCN
71 phy->ops = &b43_phyops_lcn;
72#endif
73 break;
68 } 74 }
69 if (B43_WARN_ON(!phy->ops)) 75 if (B43_WARN_ON(!phy->ops))
70 return -ENODEV; 76 return -ENODEV;
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 47dcb800a3c3..aa77ba612a92 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -195,6 +195,7 @@ struct b43_phy_g;
195struct b43_phy_n; 195struct b43_phy_n;
196struct b43_phy_lp; 196struct b43_phy_lp;
197struct b43_phy_ht; 197struct b43_phy_ht;
198struct b43_phy_lcn;
198 199
199struct b43_phy { 200struct b43_phy {
200 /* Hardware operation callbacks. */ 201 /* Hardware operation callbacks. */
@@ -219,6 +220,8 @@ struct b43_phy {
219 struct b43_phy_lp *lp; 220 struct b43_phy_lp *lp;
220 /* HT-PHY specific information */ 221 /* HT-PHY specific information */
221 struct b43_phy_ht *ht; 222 struct b43_phy_ht *ht;
223 /* LCN-PHY specific information */
224 struct b43_phy_lcn *lcn;
222 }; 225 };
223 226
224 /* Band support flags. */ 227 /* Band support flags. */
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 30b19c61037d..29821036badf 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -373,6 +373,16 @@ static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
373 b43_write16(dev, B43_MMIO_RADIO24_DATA, value); 373 b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
374} 374}
375 375
376static enum b43_txpwr_result
377b43_phy_ht_op_recalc_txpower(struct b43_wldev *dev, bool ignore_tssi)
378{
379 return B43_TXPWR_RES_DONE;
380}
381
382static void b43_phy_ht_op_adjust_txpower(struct b43_wldev *dev)
383{
384}
385
376/************************************************** 386/**************************************************
377 * PHY ops struct. 387 * PHY ops struct.
378 **************************************************/ 388 **************************************************/
@@ -391,8 +401,6 @@ const struct b43_phy_operations b43_phyops_ht = {
391 .switch_analog = b43_phy_ht_op_switch_analog, 401 .switch_analog = b43_phy_ht_op_switch_analog,
392 .switch_channel = b43_phy_ht_op_switch_channel, 402 .switch_channel = b43_phy_ht_op_switch_channel,
393 .get_default_chan = b43_phy_ht_op_get_default_chan, 403 .get_default_chan = b43_phy_ht_op_get_default_chan,
394 /*
395 .recalc_txpower = b43_phy_ht_op_recalc_txpower, 404 .recalc_txpower = b43_phy_ht_op_recalc_txpower,
396 .adjust_txpower = b43_phy_ht_op_adjust_txpower, 405 .adjust_txpower = b43_phy_ht_op_adjust_txpower,
397 */
398}; 406};
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
new file mode 100644
index 000000000000..9f7dbbd5ced6
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -0,0 +1,52 @@
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11n LCN-PHY support
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20
21*/
22
23#include <linux/slab.h>
24
25#include "b43.h"
26#include "phy_lcn.h"
27#include "tables_phy_lcn.h"
28#include "main.h"
29
30/**************************************************
31 * PHY ops struct.
32 **************************************************/
33
34const struct b43_phy_operations b43_phyops_lcn = {
35 /*
36 .allocate = b43_phy_lcn_op_allocate,
37 .free = b43_phy_lcn_op_free,
38 .prepare_structs = b43_phy_lcn_op_prepare_structs,
39 .init = b43_phy_lcn_op_init,
40 .phy_read = b43_phy_lcn_op_read,
41 .phy_write = b43_phy_lcn_op_write,
42 .phy_maskset = b43_phy_lcn_op_maskset,
43 .radio_read = b43_phy_lcn_op_radio_read,
44 .radio_write = b43_phy_lcn_op_radio_write,
45 .software_rfkill = b43_phy_lcn_op_software_rfkill,
46 .switch_analog = b43_phy_lcn_op_switch_analog,
47 .switch_channel = b43_phy_lcn_op_switch_channel,
48 .get_default_chan = b43_phy_lcn_op_get_default_chan,
49 .recalc_txpower = b43_phy_lcn_op_recalc_txpower,
50 .adjust_txpower = b43_phy_lcn_op_adjust_txpower,
51 */
52};
diff --git a/drivers/net/wireless/b43/phy_lcn.h b/drivers/net/wireless/b43/phy_lcn.h
new file mode 100644
index 000000000000..c046c2a6cab4
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_lcn.h
@@ -0,0 +1,14 @@
1#ifndef B43_PHY_LCN_H_
2#define B43_PHY_LCN_H_
3
4#include "phy_common.h"
5
6
7struct b43_phy_lcn {
8};
9
10
11struct b43_phy_operations;
12extern const struct b43_phy_operations b43_phyops_lcn;
13
14#endif /* B43_PHY_LCN_H_ */ \ No newline at end of file
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index e7dfdac9e4d7..95c28f584ed9 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -603,17 +603,33 @@ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
603/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */ 603/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
604static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force) 604static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
605{ 605{
606 u32 tmslow; 606 u32 tmp;
607 607
608 if (dev->phy.type != B43_PHYTYPE_N) 608 if (dev->phy.type != B43_PHYTYPE_N)
609 return; 609 return;
610 610
611 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); 611 switch (dev->dev->bus_type) {
612 if (force) 612#ifdef CONFIG_B43_BCMA
613 tmslow |= SSB_TMSLOW_FGC; 613 case B43_BUS_BCMA:
614 else 614 tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL);
615 tmslow &= ~SSB_TMSLOW_FGC; 615 if (force)
616 ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); 616 tmp |= BCMA_IOCTL_FGC;
617 else
618 tmp &= ~BCMA_IOCTL_FGC;
619 bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp);
620 break;
621#endif
622#ifdef CONFIG_B43_SSB
623 case B43_BUS_SSB:
624 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
625 if (force)
626 tmp |= SSB_TMSLOW_FGC;
627 else
628 tmp &= ~SSB_TMSLOW_FGC;
629 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
630 break;
631#endif
632 }
617} 633}
618 634
619/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ 635/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
@@ -958,8 +974,21 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
958 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); 974 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
959 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); 975 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
960 976
961 ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00, 977 switch (dev->dev->bus_type) {
962 0xFC00); 978#ifdef CONFIG_B43_BCMA
979 case B43_BUS_BCMA:
980 bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc,
981 0xFC00, 0xFC00);
982 break;
983#endif
984#ifdef CONFIG_B43_SSB
985 case B43_BUS_SSB:
986 ssb_chipco_gpio_control(&dev->dev->sdev->bus->chipco,
987 0xFC00, 0xFC00);
988 break;
989#endif
990 }
991
963 b43_write32(dev, B43_MMIO_MACCTL, 992 b43_write32(dev, B43_MMIO_MACCTL,
964 b43_read32(dev, B43_MMIO_MACCTL) & 993 b43_read32(dev, B43_MMIO_MACCTL) &
965 ~B43_MACCTL_GPOUTSMSK); 994 ~B43_MACCTL_GPOUTSMSK);
@@ -3600,7 +3629,20 @@ int b43_phy_initn(struct b43_wldev *dev)
3600 if ((dev->phy.rev >= 3) && 3629 if ((dev->phy.rev >= 3) &&
3601 (sprom->boardflags_lo & B43_BFL_EXTLNA) && 3630 (sprom->boardflags_lo & B43_BFL_EXTLNA) &&
3602 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { 3631 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
3603 chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); 3632 switch (dev->dev->bus_type) {
3633#ifdef CONFIG_B43_BCMA
3634 case B43_BUS_BCMA:
3635 bcma_cc_set32(&dev->dev->bdev->bus->drv_cc,
3636 BCMA_CC_CHIPCTL, 0x40);
3637 break;
3638#endif
3639#ifdef CONFIG_B43_SSB
3640 case B43_BUS_SSB:
3641 chipco_set32(&dev->dev->sdev->bus->chipco,
3642 SSB_CHIPCO_CHIPCTL, 0x40);
3643 break;
3644#endif
3645 }
3604 } 3646 }
3605 nphy->deaf_count = 0; 3647 nphy->deaf_count = 0;
3606 b43_nphy_tables_init(dev); 3648 b43_nphy_tables_init(dev);
diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c
new file mode 100644
index 000000000000..40c1d0915dd3
--- /dev/null
+++ b/drivers/net/wireless/b43/tables_phy_lcn.c
@@ -0,0 +1,34 @@
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11n LCN-PHY data tables
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20
21*/
22
23#include "b43.h"
24#include "tables_phy_lcn.h"
25#include "phy_common.h"
26#include "phy_lcn.h"
27
28/**************************************************
29 * Tables ops.
30 **************************************************/
31
32void b43_phy_lcn_tables_init(struct b43_wldev *dev)
33{
34}
diff --git a/drivers/net/wireless/b43/tables_phy_lcn.h b/drivers/net/wireless/b43/tables_phy_lcn.h
new file mode 100644
index 000000000000..5e31b15b81ec
--- /dev/null
+++ b/drivers/net/wireless/b43/tables_phy_lcn.h
@@ -0,0 +1,6 @@
1#ifndef B43_TABLES_PHY_LCN_H_
2#define B43_TABLES_PHY_LCN_H_
3
4void b43_phy_lcn_tables_init(struct b43_wldev *dev);
5
6#endif /* B43_TABLES_PHY_LCN_H_ */
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 488b898418a3..82bcf7595139 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -323,8 +323,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
323 /* we give the phase1key and iv16 here, the key is stored in 323 /* we give the phase1key and iv16 here, the key is stored in
324 * shm. With that the hardware can do phase 2 and encryption. 324 * shm. With that the hardware can do phase 2 and encryption.
325 */ 325 */
326 ieee80211_get_tkip_key(info->control.hw_key, skb_frag, 326 ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key);
327 IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
328 /* phase1key is in host endian. Copy to little-endian txhdr->iv. */ 327 /* phase1key is in host endian. Copy to little-endian txhdr->iv. */
329 for (i = 0; i < 5; i++) { 328 for (i = 0; i < 5; i++) {
330 txhdr->iv[i * 2 + 0] = phase1key[i]; 329 txhdr->iv[i * 2 + 0] = phase1key[i];