aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 20:48:54 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 20:48:54 -0400
commit1f1c2881f673671539b25686df463518d69c4649 (patch)
tree45f4a79f2371ae4525fd621d4b5820732efa161e /drivers/net/wireless/zd1211rw
parent7608a864e5211df1e3c1948e2719aec7c27b9333 (diff)
parentc5e3ae8823693b260ce1f217adca8add1bc0b3de (diff)
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (37 commits) forcedeth bug fix: realtek phy forcedeth bug fix: vitesse phy forcedeth bug fix: cicada phy atl1: reorder atl1_main functions atl1: fix excessively indented code atl1: cleanup atl1_main atl1: header file cleanup atl1: remove irq_sem cdc-subset to support new vendor/product ID 8139cp: implement the missing dev->tx_timeout myri10ge: Remove nonsensical limit in the tx done routine gianfar: kill unused header EP93XX_ETH must select MII macb: Add multicast capability macb: Use generic PHY layer s390: add barriers to qeth driver s390: scatter-gather for inbound traffic in qeth driver eHEA: Introducing support vor DLPAR memory add Fix a potential NULL pointer dereference in free_shared_mem() in drivers/net/s2io.c [PATCH] softmac: Fix ESSID problem ...
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c88
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h13
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c59
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.h2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c12
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al7230b.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_rf2959.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_uw2453.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c98
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h3
12 files changed, 152 insertions, 135 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 5b624bfc01a6..c39f1984b84d 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -49,8 +49,9 @@ void zd_chip_clear(struct zd_chip *chip)
49 ZD_MEMCLEAR(chip, sizeof(*chip)); 49 ZD_MEMCLEAR(chip, sizeof(*chip));
50} 50}
51 51
52static int scnprint_mac_oui(const u8 *addr, char *buffer, size_t size) 52static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size)
53{ 53{
54 u8 *addr = zd_usb_to_netdev(&chip->usb)->dev_addr;
54 return scnprintf(buffer, size, "%02x-%02x-%02x", 55 return scnprintf(buffer, size, "%02x-%02x-%02x",
55 addr[0], addr[1], addr[2]); 56 addr[0], addr[1], addr[2]);
56} 57}
@@ -61,10 +62,10 @@ static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
61 int i = 0; 62 int i = 0;
62 63
63 i = scnprintf(buffer, size, "zd1211%s chip ", 64 i = scnprintf(buffer, size, "zd1211%s chip ",
64 chip->is_zd1211b ? "b" : ""); 65 zd_chip_is_zd1211b(chip) ? "b" : "");
65 i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i); 66 i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i);
66 i += scnprintf(buffer+i, size-i, " "); 67 i += scnprintf(buffer+i, size-i, " ");
67 i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i); 68 i += scnprint_mac_oui(chip, buffer+i, size-i);
68 i += scnprintf(buffer+i, size-i, " "); 69 i += scnprintf(buffer+i, size-i, " ");
69 i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i); 70 i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
70 i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type, 71 i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type,
@@ -366,64 +367,9 @@ error:
366 return r; 367 return r;
367} 368}
368 369
369static int _read_mac_addr(struct zd_chip *chip, u8 *mac_addr,
370 const zd_addr_t *addr)
371{
372 int r;
373 u32 parts[2];
374
375 r = zd_ioread32v_locked(chip, parts, (const zd_addr_t *)addr, 2);
376 if (r) {
377 dev_dbg_f(zd_chip_dev(chip),
378 "error: couldn't read e2p macs. Error number %d\n", r);
379 return r;
380 }
381
382 mac_addr[0] = parts[0];
383 mac_addr[1] = parts[0] >> 8;
384 mac_addr[2] = parts[0] >> 16;
385 mac_addr[3] = parts[0] >> 24;
386 mac_addr[4] = parts[1];
387 mac_addr[5] = parts[1] >> 8;
388
389 return 0;
390}
391
392static int read_e2p_mac_addr(struct zd_chip *chip)
393{
394 static const zd_addr_t addr[2] = { E2P_MAC_ADDR_P1, E2P_MAC_ADDR_P2 };
395
396 ZD_ASSERT(mutex_is_locked(&chip->mutex));
397 return _read_mac_addr(chip, chip->e2p_mac, (const zd_addr_t *)addr);
398}
399
400/* MAC address: if custom mac addresses are to to be used CR_MAC_ADDR_P1 and 370/* MAC address: if custom mac addresses are to to be used CR_MAC_ADDR_P1 and
401 * CR_MAC_ADDR_P2 must be overwritten 371 * CR_MAC_ADDR_P2 must be overwritten
402 */ 372 */
403void zd_get_e2p_mac_addr(struct zd_chip *chip, u8 *mac_addr)
404{
405 mutex_lock(&chip->mutex);
406 memcpy(mac_addr, chip->e2p_mac, ETH_ALEN);
407 mutex_unlock(&chip->mutex);
408}
409
410static int read_mac_addr(struct zd_chip *chip, u8 *mac_addr)
411{
412 static const zd_addr_t addr[2] = { CR_MAC_ADDR_P1, CR_MAC_ADDR_P2 };
413 return _read_mac_addr(chip, mac_addr, (const zd_addr_t *)addr);
414}
415
416int zd_read_mac_addr(struct zd_chip *chip, u8 *mac_addr)
417{
418 int r;
419
420 dev_dbg_f(zd_chip_dev(chip), "\n");
421 mutex_lock(&chip->mutex);
422 r = read_mac_addr(chip, mac_addr);
423 mutex_unlock(&chip->mutex);
424 return r;
425}
426
427int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) 373int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
428{ 374{
429 int r; 375 int r;
@@ -444,12 +390,6 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
444 390
445 mutex_lock(&chip->mutex); 391 mutex_lock(&chip->mutex);
446 r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); 392 r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
447#ifdef DEBUG
448 {
449 u8 tmp[ETH_ALEN];
450 read_mac_addr(chip, tmp);
451 }
452#endif /* DEBUG */
453 mutex_unlock(&chip->mutex); 393 mutex_unlock(&chip->mutex);
454 return r; 394 return r;
455} 395}
@@ -809,7 +749,7 @@ out:
809 749
810static int hw_reset_phy(struct zd_chip *chip) 750static int hw_reset_phy(struct zd_chip *chip)
811{ 751{
812 return chip->is_zd1211b ? zd1211b_hw_reset_phy(chip) : 752 return zd_chip_is_zd1211b(chip) ? zd1211b_hw_reset_phy(chip) :
813 zd1211_hw_reset_phy(chip); 753 zd1211_hw_reset_phy(chip);
814} 754}
815 755
@@ -874,7 +814,7 @@ static int hw_init_hmac(struct zd_chip *chip)
874 if (r) 814 if (r)
875 return r; 815 return r;
876 816
877 return chip->is_zd1211b ? 817 return zd_chip_is_zd1211b(chip) ?
878 zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip); 818 zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip);
879} 819}
880 820
@@ -1136,8 +1076,15 @@ static int read_fw_regs_offset(struct zd_chip *chip)
1136 return 0; 1076 return 0;
1137} 1077}
1138 1078
1079/* Read mac address using pre-firmware interface */
1080int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr)
1081{
1082 dev_dbg_f(zd_chip_dev(chip), "\n");
1083 return zd_usb_read_fw(&chip->usb, E2P_MAC_ADDR_P1, addr,
1084 ETH_ALEN);
1085}
1139 1086
1140int zd_chip_init_hw(struct zd_chip *chip, u8 device_type) 1087int zd_chip_init_hw(struct zd_chip *chip)
1141{ 1088{
1142 int r; 1089 int r;
1143 u8 rf_type; 1090 u8 rf_type;
@@ -1145,7 +1092,6 @@ int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
1145 dev_dbg_f(zd_chip_dev(chip), "\n"); 1092 dev_dbg_f(zd_chip_dev(chip), "\n");
1146 1093
1147 mutex_lock(&chip->mutex); 1094 mutex_lock(&chip->mutex);
1148 chip->is_zd1211b = (device_type == DEVICE_ZD1211B) != 0;
1149 1095
1150#ifdef DEBUG 1096#ifdef DEBUG
1151 r = test_init(chip); 1097 r = test_init(chip);
@@ -1201,10 +1147,6 @@ int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
1201 goto out; 1147 goto out;
1202#endif /* DEBUG */ 1148#endif /* DEBUG */
1203 1149
1204 r = read_e2p_mac_addr(chip);
1205 if (r)
1206 goto out;
1207
1208 r = read_cal_int_tables(chip); 1150 r = read_cal_int_tables(chip);
1209 if (r) 1151 if (r)
1210 goto out; 1152 goto out;
@@ -1259,7 +1201,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
1259 r = update_pwr_int(chip, channel); 1201 r = update_pwr_int(chip, channel);
1260 if (r) 1202 if (r)
1261 return r; 1203 return r;
1262 if (chip->is_zd1211b) { 1204 if (zd_chip_is_zd1211b(chip)) {
1263 static const struct zd_ioreq16 ioreqs[] = { 1205 static const struct zd_ioreq16 ioreqs[] = {
1264 { CR69, 0x28 }, 1206 { CR69, 0x28 },
1265 {}, 1207 {},
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index 79d0288c193a..f4698576ab71 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -704,7 +704,6 @@ struct zd_chip {
704 struct mutex mutex; 704 struct mutex mutex;
705 /* Base address of FW_REG_ registers */ 705 /* Base address of FW_REG_ registers */
706 zd_addr_t fw_regs_base; 706 zd_addr_t fw_regs_base;
707 u8 e2p_mac[ETH_ALEN];
708 /* EepSetPoint in the vendor driver */ 707 /* EepSetPoint in the vendor driver */
709 u8 pwr_cal_values[E2P_CHANNEL_COUNT]; 708 u8 pwr_cal_values[E2P_CHANNEL_COUNT];
710 /* integration values in the vendor driver */ 709 /* integration values in the vendor driver */
@@ -715,7 +714,7 @@ struct zd_chip {
715 unsigned int pa_type:4, 714 unsigned int pa_type:4,
716 patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1, 715 patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
717 new_phy_layout:1, al2230s_bit:1, 716 new_phy_layout:1, al2230s_bit:1,
718 is_zd1211b:1, supports_tx_led:1; 717 supports_tx_led:1;
719}; 718};
720 719
721static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb) 720static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb)
@@ -734,9 +733,15 @@ void zd_chip_init(struct zd_chip *chip,
734 struct net_device *netdev, 733 struct net_device *netdev,
735 struct usb_interface *intf); 734 struct usb_interface *intf);
736void zd_chip_clear(struct zd_chip *chip); 735void zd_chip_clear(struct zd_chip *chip);
737int zd_chip_init_hw(struct zd_chip *chip, u8 device_type); 736int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr);
737int zd_chip_init_hw(struct zd_chip *chip);
738int zd_chip_reset(struct zd_chip *chip); 738int zd_chip_reset(struct zd_chip *chip);
739 739
740static inline int zd_chip_is_zd1211b(struct zd_chip *chip)
741{
742 return chip->usb.is_zd1211b;
743}
744
740static inline int zd_ioread16v_locked(struct zd_chip *chip, u16 *values, 745static inline int zd_ioread16v_locked(struct zd_chip *chip, u16 *values,
741 const zd_addr_t *addresses, 746 const zd_addr_t *addresses,
742 unsigned int count) 747 unsigned int count)
@@ -825,8 +830,6 @@ static inline u8 _zd_chip_get_channel(struct zd_chip *chip)
825} 830}
826u8 zd_chip_get_channel(struct zd_chip *chip); 831u8 zd_chip_get_channel(struct zd_chip *chip);
827int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain); 832int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain);
828void zd_get_e2p_mac_addr(struct zd_chip *chip, u8 *mac_addr);
829int zd_read_mac_addr(struct zd_chip *chip, u8 *mac_addr);
830int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr); 833int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr);
831int zd_chip_switch_radio_on(struct zd_chip *chip); 834int zd_chip_switch_radio_on(struct zd_chip *chip);
832int zd_chip_switch_radio_off(struct zd_chip *chip); 835int zd_chip_switch_radio_off(struct zd_chip *chip);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 6753d240c168..f6c487aa8246 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -86,38 +86,46 @@ out:
86 return r; 86 return r;
87} 87}
88 88
89int zd_mac_init_hw(struct zd_mac *mac, u8 device_type) 89int zd_mac_preinit_hw(struct zd_mac *mac)
90{ 90{
91 int r; 91 int r;
92 struct zd_chip *chip = &mac->chip;
93 u8 addr[ETH_ALEN]; 92 u8 addr[ETH_ALEN];
93
94 r = zd_chip_read_mac_addr_fw(&mac->chip, addr);
95 if (r)
96 return r;
97
98 memcpy(mac->netdev->dev_addr, addr, ETH_ALEN);
99 return 0;
100}
101
102int zd_mac_init_hw(struct zd_mac *mac)
103{
104 int r;
105 struct zd_chip *chip = &mac->chip;
94 u8 default_regdomain; 106 u8 default_regdomain;
95 107
96 r = zd_chip_enable_int(chip); 108 r = zd_chip_enable_int(chip);
97 if (r) 109 if (r)
98 goto out; 110 goto out;
99 r = zd_chip_init_hw(chip, device_type); 111 r = zd_chip_init_hw(chip);
100 if (r) 112 if (r)
101 goto disable_int; 113 goto disable_int;
102 114
103 zd_get_e2p_mac_addr(chip, addr);
104 r = zd_write_mac_addr(chip, addr);
105 if (r)
106 goto disable_int;
107 ZD_ASSERT(!irqs_disabled()); 115 ZD_ASSERT(!irqs_disabled());
108 spin_lock_irq(&mac->lock);
109 memcpy(mac->netdev->dev_addr, addr, ETH_ALEN);
110 spin_unlock_irq(&mac->lock);
111 116
112 r = zd_read_regdomain(chip, &default_regdomain); 117 r = zd_read_regdomain(chip, &default_regdomain);
113 if (r) 118 if (r)
114 goto disable_int; 119 goto disable_int;
115 if (!zd_regdomain_supported(default_regdomain)) { 120 if (!zd_regdomain_supported(default_regdomain)) {
116 dev_dbg_f(zd_mac_dev(mac), 121 /* The vendor driver overrides the regulatory domain and
117 "Regulatory Domain %#04x is not supported.\n", 122 * allowed channel registers and unconditionally restricts
118 default_regdomain); 123 * available channels to 1-11 everywhere. Match their
119 r = -EINVAL; 124 * questionable behaviour only for regdomains which we don't
120 goto disable_int; 125 * recognise. */
126 dev_warn(zd_mac_dev(mac), "Unrecognised regulatory domain: "
127 "%#04x. Defaulting to FCC.\n", default_regdomain);
128 default_regdomain = ZD_REGDOMAIN_FCC;
121 } 129 }
122 spin_lock_irq(&mac->lock); 130 spin_lock_irq(&mac->lock);
123 mac->regdomain = mac->default_regdomain = default_regdomain; 131 mac->regdomain = mac->default_regdomain = default_regdomain;
@@ -164,14 +172,25 @@ int zd_mac_open(struct net_device *netdev)
164{ 172{
165 struct zd_mac *mac = zd_netdev_mac(netdev); 173 struct zd_mac *mac = zd_netdev_mac(netdev);
166 struct zd_chip *chip = &mac->chip; 174 struct zd_chip *chip = &mac->chip;
175 struct zd_usb *usb = &chip->usb;
167 int r; 176 int r;
168 177
178 if (!usb->initialized) {
179 r = zd_usb_init_hw(usb);
180 if (r)
181 goto out;
182 }
183
169 tasklet_enable(&mac->rx_tasklet); 184 tasklet_enable(&mac->rx_tasklet);
170 185
171 r = zd_chip_enable_int(chip); 186 r = zd_chip_enable_int(chip);
172 if (r < 0) 187 if (r < 0)
173 goto out; 188 goto out;
174 189
190 r = zd_write_mac_addr(chip, netdev->dev_addr);
191 if (r)
192 goto disable_int;
193
175 r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); 194 r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G);
176 if (r < 0) 195 if (r < 0)
177 goto disable_int; 196 goto disable_int;
@@ -251,9 +270,11 @@ int zd_mac_set_mac_address(struct net_device *netdev, void *p)
251 dev_dbg_f(zd_mac_dev(mac), 270 dev_dbg_f(zd_mac_dev(mac),
252 "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data)); 271 "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data));
253 272
254 r = zd_write_mac_addr(chip, addr->sa_data); 273 if (netdev->flags & IFF_UP) {
255 if (r) 274 r = zd_write_mac_addr(chip, addr->sa_data);
256 return r; 275 if (r)
276 return r;
277 }
257 278
258 spin_lock_irqsave(&mac->lock, flags); 279 spin_lock_irqsave(&mac->lock, flags);
259 memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN); 280 memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN);
@@ -855,7 +876,7 @@ static int fill_ctrlset(struct zd_mac *mac,
855 /* ZD1211B: Computing the length difference this way, gives us 876 /* ZD1211B: Computing the length difference this way, gives us
856 * flexibility to compute the packet length. 877 * flexibility to compute the packet length.
857 */ 878 */
858 cs->packet_length = cpu_to_le16(mac->chip.is_zd1211b ? 879 cs->packet_length = cpu_to_le16(zd_chip_is_zd1211b(&mac->chip) ?
859 packet_length - frag_len : packet_length); 880 packet_length - frag_len : packet_length);
860 881
861 /* 882 /*
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index faf4c7828d4e..9f9344eb50f9 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -189,7 +189,8 @@ int zd_mac_init(struct zd_mac *mac,
189 struct usb_interface *intf); 189 struct usb_interface *intf);
190void zd_mac_clear(struct zd_mac *mac); 190void zd_mac_clear(struct zd_mac *mac);
191 191
192int zd_mac_init_hw(struct zd_mac *mac, u8 device_type); 192int zd_mac_preinit_hw(struct zd_mac *mac);
193int zd_mac_init_hw(struct zd_mac *mac);
193 194
194int zd_mac_open(struct net_device *netdev); 195int zd_mac_open(struct net_device *netdev);
195int zd_mac_stop(struct net_device *netdev); 196int zd_mac_stop(struct net_device *netdev);
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
index 7407409b60b1..abe5d38f7f4d 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -34,7 +34,7 @@ static const char * const rfs[] = {
34 [AL2210_RF] = "AL2210_RF", 34 [AL2210_RF] = "AL2210_RF",
35 [MAXIM_NEW_RF] = "MAXIM_NEW_RF", 35 [MAXIM_NEW_RF] = "MAXIM_NEW_RF",
36 [UW2453_RF] = "UW2453_RF", 36 [UW2453_RF] = "UW2453_RF",
37 [UNKNOWN_A_RF] = "UNKNOWN_A_RF", 37 [AL2230S_RF] = "AL2230S_RF",
38 [RALINK_RF] = "RALINK_RF", 38 [RALINK_RF] = "RALINK_RF",
39 [INTERSIL_RF] = "INTERSIL_RF", 39 [INTERSIL_RF] = "INTERSIL_RF",
40 [RF2959_RF] = "RF2959_RF", 40 [RF2959_RF] = "RF2959_RF",
@@ -77,6 +77,7 @@ int zd_rf_init_hw(struct zd_rf *rf, u8 type)
77 r = zd_rf_init_rf2959(rf); 77 r = zd_rf_init_rf2959(rf);
78 break; 78 break;
79 case AL2230_RF: 79 case AL2230_RF:
80 case AL2230S_RF:
80 r = zd_rf_init_al2230(rf); 81 r = zd_rf_init_al2230(rf);
81 break; 82 break;
82 case AL7230B_RF: 83 case AL7230B_RF:
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
index c6dfd8227f6e..30502f26b71c 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.h
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -26,7 +26,7 @@
26#define AL2210_RF 0x7 26#define AL2210_RF 0x7
27#define MAXIM_NEW_RF 0x8 27#define MAXIM_NEW_RF 0x8
28#define UW2453_RF 0x9 28#define UW2453_RF 0x9
29#define UNKNOWN_A_RF 0xa 29#define AL2230S_RF 0xa
30#define RALINK_RF 0xb 30#define RALINK_RF 0xb
31#define INTERSIL_RF 0xc 31#define INTERSIL_RF 0xc
32#define RF2959_RF 0xd 32#define RF2959_RF 0xd
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index e7a4ecf7b6e2..006774de3202 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -21,6 +21,8 @@
21#include "zd_usb.h" 21#include "zd_usb.h"
22#include "zd_chip.h" 22#include "zd_chip.h"
23 23
24#define IS_AL2230S(chip) ((chip)->al2230s_bit || (chip)->rf.type == AL2230S_RF)
25
24static const u32 zd1211_al2230_table[][3] = { 26static const u32 zd1211_al2230_table[][3] = {
25 RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, }, 27 RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, },
26 RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, }, 28 RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, },
@@ -176,7 +178,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
176 if (r) 178 if (r)
177 return r; 179 return r;
178 180
179 if (chip->al2230s_bit) { 181 if (IS_AL2230S(chip)) {
180 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s, 182 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
181 ARRAY_SIZE(ioreqs_init_al2230s)); 183 ARRAY_SIZE(ioreqs_init_al2230s));
182 if (r) 184 if (r)
@@ -188,7 +190,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
188 return r; 190 return r;
189 191
190 /* improve band edge for AL2230S */ 192 /* improve band edge for AL2230S */
191 if (chip->al2230s_bit) 193 if (IS_AL2230S(chip))
192 r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS); 194 r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS);
193 else 195 else
194 r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS); 196 r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS);
@@ -314,7 +316,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
314 if (r) 316 if (r)
315 return r; 317 return r;
316 318
317 if (chip->al2230s_bit) { 319 if (IS_AL2230S(chip)) {
318 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s, 320 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
319 ARRAY_SIZE(ioreqs_init_al2230s)); 321 ARRAY_SIZE(ioreqs_init_al2230s));
320 if (r) 322 if (r)
@@ -328,7 +330,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
328 if (r) 330 if (r)
329 return r; 331 return r;
330 332
331 if (chip->al2230s_bit) 333 if (IS_AL2230S(chip))
332 r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS); 334 r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS);
333 else 335 else
334 r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS); 336 r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS);
@@ -422,7 +424,7 @@ int zd_rf_init_al2230(struct zd_rf *rf)
422 struct zd_chip *chip = zd_rf_to_chip(rf); 424 struct zd_chip *chip = zd_rf_to_chip(rf);
423 425
424 rf->switch_radio_off = al2230_switch_radio_off; 426 rf->switch_radio_off = al2230_switch_radio_off;
425 if (chip->is_zd1211b) { 427 if (zd_chip_is_zd1211b(chip)) {
426 rf->init_hw = zd1211b_al2230_init_hw; 428 rf->init_hw = zd1211b_al2230_init_hw;
427 rf->set_channel = zd1211b_al2230_set_channel; 429 rf->set_channel = zd1211b_al2230_set_channel;
428 rf->switch_radio_on = zd1211b_al2230_switch_radio_on; 430 rf->switch_radio_on = zd1211b_al2230_switch_radio_on;
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
index f4e8b6ada854..73d0bb26f810 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
@@ -473,7 +473,7 @@ int zd_rf_init_al7230b(struct zd_rf *rf)
473{ 473{
474 struct zd_chip *chip = zd_rf_to_chip(rf); 474 struct zd_chip *chip = zd_rf_to_chip(rf);
475 475
476 if (chip->is_zd1211b) { 476 if (zd_chip_is_zd1211b(chip)) {
477 rf->init_hw = zd1211b_al7230b_init_hw; 477 rf->init_hw = zd1211b_al7230b_init_hw;
478 rf->switch_radio_on = zd1211b_al7230b_switch_radio_on; 478 rf->switch_radio_on = zd1211b_al7230b_switch_radio_on;
479 rf->set_channel = zd1211b_al7230b_set_channel; 479 rf->set_channel = zd1211b_al7230b_set_channel;
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
index 2d736bdf707c..cc70d40684ea 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
@@ -265,7 +265,7 @@ int zd_rf_init_rf2959(struct zd_rf *rf)
265{ 265{
266 struct zd_chip *chip = zd_rf_to_chip(rf); 266 struct zd_chip *chip = zd_rf_to_chip(rf);
267 267
268 if (chip->is_zd1211b) { 268 if (zd_chip_is_zd1211b(chip)) {
269 dev_err(zd_chip_dev(chip), 269 dev_err(zd_chip_dev(chip),
270 "RF2959 is currently not supported for ZD1211B" 270 "RF2959 is currently not supported for ZD1211B"
271 " devices\n"); 271 " devices\n");
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
index 414e40d571ab..857dcf3eae61 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
@@ -486,7 +486,7 @@ static int uw2453_switch_radio_on(struct zd_rf *rf)
486 if (r) 486 if (r)
487 return r; 487 return r;
488 488
489 if (chip->is_zd1211b) 489 if (zd_chip_is_zd1211b(chip))
490 ioreqs[1].value = 0x7f; 490 ioreqs[1].value = 0x7f;
491 491
492 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 492 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index ca24299a26c6..28d41a29d7b1 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -71,6 +71,7 @@ static struct usb_device_id usb_ids[] = {
71 { USB_DEVICE(0x0586, 0x3412), .driver_info = DEVICE_ZD1211B }, 71 { USB_DEVICE(0x0586, 0x3412), .driver_info = DEVICE_ZD1211B },
72 { USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B }, 72 { USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B },
73 { USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B }, 73 { USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B },
74 { USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B },
74 /* "Driverless" devices that need ejecting */ 75 /* "Driverless" devices that need ejecting */
75 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, 76 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
76 { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, 77 { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
@@ -195,26 +196,27 @@ static u16 get_word(const void *data, u16 offset)
195 return le16_to_cpu(p[offset]); 196 return le16_to_cpu(p[offset]);
196} 197}
197 198
198static char *get_fw_name(char *buffer, size_t size, u8 device_type, 199static char *get_fw_name(struct zd_usb *usb, char *buffer, size_t size,
199 const char* postfix) 200 const char* postfix)
200{ 201{
201 scnprintf(buffer, size, "%s%s", 202 scnprintf(buffer, size, "%s%s",
202 device_type == DEVICE_ZD1211B ? 203 usb->is_zd1211b ?
203 FW_ZD1211B_PREFIX : FW_ZD1211_PREFIX, 204 FW_ZD1211B_PREFIX : FW_ZD1211_PREFIX,
204 postfix); 205 postfix);
205 return buffer; 206 return buffer;
206} 207}
207 208
208static int handle_version_mismatch(struct usb_device *udev, u8 device_type, 209static int handle_version_mismatch(struct zd_usb *usb,
209 const struct firmware *ub_fw) 210 const struct firmware *ub_fw)
210{ 211{
212 struct usb_device *udev = zd_usb_to_usbdev(usb);
211 const struct firmware *ur_fw = NULL; 213 const struct firmware *ur_fw = NULL;
212 int offset; 214 int offset;
213 int r = 0; 215 int r = 0;
214 char fw_name[128]; 216 char fw_name[128];
215 217
216 r = request_fw_file(&ur_fw, 218 r = request_fw_file(&ur_fw,
217 get_fw_name(fw_name, sizeof(fw_name), device_type, "ur"), 219 get_fw_name(usb, fw_name, sizeof(fw_name), "ur"),
218 &udev->dev); 220 &udev->dev);
219 if (r) 221 if (r)
220 goto error; 222 goto error;
@@ -237,11 +239,12 @@ error:
237 return r; 239 return r;
238} 240}
239 241
240static int upload_firmware(struct usb_device *udev, u8 device_type) 242static int upload_firmware(struct zd_usb *usb)
241{ 243{
242 int r; 244 int r;
243 u16 fw_bcdDevice; 245 u16 fw_bcdDevice;
244 u16 bcdDevice; 246 u16 bcdDevice;
247 struct usb_device *udev = zd_usb_to_usbdev(usb);
245 const struct firmware *ub_fw = NULL; 248 const struct firmware *ub_fw = NULL;
246 const struct firmware *uph_fw = NULL; 249 const struct firmware *uph_fw = NULL;
247 char fw_name[128]; 250 char fw_name[128];
@@ -249,7 +252,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
249 bcdDevice = get_bcdDevice(udev); 252 bcdDevice = get_bcdDevice(udev);
250 253
251 r = request_fw_file(&ub_fw, 254 r = request_fw_file(&ub_fw,
252 get_fw_name(fw_name, sizeof(fw_name), device_type, "ub"), 255 get_fw_name(usb, fw_name, sizeof(fw_name), "ub"),
253 &udev->dev); 256 &udev->dev);
254 if (r) 257 if (r)
255 goto error; 258 goto error;
@@ -264,7 +267,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
264 dev_warn(&udev->dev, "device has old bootcode, please " 267 dev_warn(&udev->dev, "device has old bootcode, please "
265 "report success or failure\n"); 268 "report success or failure\n");
266 269
267 r = handle_version_mismatch(udev, device_type, ub_fw); 270 r = handle_version_mismatch(usb, ub_fw);
268 if (r) 271 if (r)
269 goto error; 272 goto error;
270 } else { 273 } else {
@@ -275,7 +278,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
275 278
276 279
277 r = request_fw_file(&uph_fw, 280 r = request_fw_file(&uph_fw,
278 get_fw_name(fw_name, sizeof(fw_name), device_type, "uphr"), 281 get_fw_name(usb, fw_name, sizeof(fw_name), "uphr"),
279 &udev->dev); 282 &udev->dev);
280 if (r) 283 if (r)
281 goto error; 284 goto error;
@@ -294,6 +297,30 @@ error:
294 return r; 297 return r;
295} 298}
296 299
300/* Read data from device address space using "firmware interface" which does
301 * not require firmware to be loaded. */
302int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len)
303{
304 int r;
305 struct usb_device *udev = zd_usb_to_usbdev(usb);
306
307 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
308 USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0,
309 data, len, 5000);
310 if (r < 0) {
311 dev_err(&udev->dev,
312 "read over firmware interface failed: %d\n", r);
313 return r;
314 } else if (r != len) {
315 dev_err(&udev->dev,
316 "incomplete read over firmware interface: %d/%d\n",
317 r, len);
318 return -EIO;
319 }
320
321 return 0;
322}
323
297#define urb_dev(urb) (&(urb)->dev->dev) 324#define urb_dev(urb) (&(urb)->dev->dev)
298 325
299static inline void handle_regs_int(struct urb *urb) 326static inline void handle_regs_int(struct urb *urb)
@@ -920,9 +947,42 @@ static int eject_installer(struct usb_interface *intf)
920 return 0; 947 return 0;
921} 948}
922 949
950int zd_usb_init_hw(struct zd_usb *usb)
951{
952 int r;
953 struct zd_mac *mac = zd_usb_to_mac(usb);
954
955 dev_dbg_f(zd_usb_dev(usb), "\n");
956
957 r = upload_firmware(usb);
958 if (r) {
959 dev_err(zd_usb_dev(usb),
960 "couldn't load firmware. Error number %d\n", r);
961 return r;
962 }
963
964 r = usb_reset_configuration(zd_usb_to_usbdev(usb));
965 if (r) {
966 dev_dbg_f(zd_usb_dev(usb),
967 "couldn't reset configuration. Error number %d\n", r);
968 return r;
969 }
970
971 r = zd_mac_init_hw(mac);
972 if (r) {
973 dev_dbg_f(zd_usb_dev(usb),
974 "couldn't initialize mac. Error number %d\n", r);
975 return r;
976 }
977
978 usb->initialized = 1;
979 return 0;
980}
981
923static int probe(struct usb_interface *intf, const struct usb_device_id *id) 982static int probe(struct usb_interface *intf, const struct usb_device_id *id)
924{ 983{
925 int r; 984 int r;
985 struct zd_usb *usb;
926 struct usb_device *udev = interface_to_usbdev(intf); 986 struct usb_device *udev = interface_to_usbdev(intf);
927 struct net_device *netdev = NULL; 987 struct net_device *netdev = NULL;
928 988
@@ -950,26 +1010,10 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id)
950 goto error; 1010 goto error;
951 } 1011 }
952 1012
953 r = upload_firmware(udev, id->driver_info); 1013 usb = &zd_netdev_mac(netdev)->chip.usb;
954 if (r) { 1014 usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0;
955 dev_err(&intf->dev,
956 "couldn't load firmware. Error number %d\n", r);
957 goto error;
958 }
959 1015
960 r = usb_reset_configuration(udev); 1016 r = zd_mac_preinit_hw(zd_netdev_mac(netdev));
961 if (r) {
962 dev_dbg_f(&intf->dev,
963 "couldn't reset configuration. Error number %d\n", r);
964 goto error;
965 }
966
967 /* At this point the interrupt endpoint is not generally enabled. We
968 * save the USB bandwidth until the network device is opened. But
969 * notify that the initialization of the MAC will require the
970 * interrupts to be temporary enabled.
971 */
972 r = zd_mac_init_hw(zd_netdev_mac(netdev), id->driver_info);
973 if (r) { 1017 if (r) {
974 dev_dbg_f(&intf->dev, 1018 dev_dbg_f(&intf->dev,
975 "couldn't initialize mac. Error number %d\n", r); 1019 "couldn't initialize mac. Error number %d\n", r);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index 506ea6a74393..961a7a12ad68 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -188,6 +188,7 @@ struct zd_usb {
188 struct zd_usb_rx rx; 188 struct zd_usb_rx rx;
189 struct zd_usb_tx tx; 189 struct zd_usb_tx tx;
190 struct usb_interface *intf; 190 struct usb_interface *intf;
191 u8 is_zd1211b:1, initialized:1;
191}; 192};
192 193
193#define zd_usb_dev(usb) (&usb->intf->dev) 194#define zd_usb_dev(usb) (&usb->intf->dev)
@@ -236,6 +237,8 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
236 237
237int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits); 238int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits);
238 239
240int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len);
241
239extern struct workqueue_struct *zd_workqueue; 242extern struct workqueue_struct *zd_workqueue;
240 243
241#endif /* _ZD_USB_H */ 244#endif /* _ZD_USB_H */