aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-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.c46
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c2
-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.c97
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h3
10 files changed, 134 insertions, 124 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 522de3f0dfaf..f6c487aa8246 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -86,28 +86,33 @@ 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)
@@ -167,14 +172,25 @@ int zd_mac_open(struct net_device *netdev)
167{ 172{
168 struct zd_mac *mac = zd_netdev_mac(netdev); 173 struct zd_mac *mac = zd_netdev_mac(netdev);
169 struct zd_chip *chip = &mac->chip; 174 struct zd_chip *chip = &mac->chip;
175 struct zd_usb *usb = &chip->usb;
170 int r; 176 int r;
171 177
178 if (!usb->initialized) {
179 r = zd_usb_init_hw(usb);
180 if (r)
181 goto out;
182 }
183
172 tasklet_enable(&mac->rx_tasklet); 184 tasklet_enable(&mac->rx_tasklet);
173 185
174 r = zd_chip_enable_int(chip); 186 r = zd_chip_enable_int(chip);
175 if (r < 0) 187 if (r < 0)
176 goto out; 188 goto out;
177 189
190 r = zd_write_mac_addr(chip, netdev->dev_addr);
191 if (r)
192 goto disable_int;
193
178 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);
179 if (r < 0) 195 if (r < 0)
180 goto disable_int; 196 goto disable_int;
@@ -254,9 +270,11 @@ int zd_mac_set_mac_address(struct net_device *netdev, void *p)
254 dev_dbg_f(zd_mac_dev(mac), 270 dev_dbg_f(zd_mac_dev(mac),
255 "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data)); 271 "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data));
256 272
257 r = zd_write_mac_addr(chip, addr->sa_data); 273 if (netdev->flags & IFF_UP) {
258 if (r) 274 r = zd_write_mac_addr(chip, addr->sa_data);
259 return r; 275 if (r)
276 return r;
277 }
260 278
261 spin_lock_irqsave(&mac->lock, flags); 279 spin_lock_irqsave(&mac->lock, flags);
262 memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN); 280 memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN);
@@ -858,7 +876,7 @@ static int fill_ctrlset(struct zd_mac *mac,
858 /* ZD1211B: Computing the length difference this way, gives us 876 /* ZD1211B: Computing the length difference this way, gives us
859 * flexibility to compute the packet length. 877 * flexibility to compute the packet length.
860 */ 878 */
861 cs->packet_length = cpu_to_le16(mac->chip.is_zd1211b ? 879 cs->packet_length = cpu_to_le16(zd_chip_is_zd1211b(&mac->chip) ?
862 packet_length - frag_len : packet_length); 880 packet_length - frag_len : packet_length);
863 881
864 /* 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_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index be9259eea088..006774de3202 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -424,7 +424,7 @@ int zd_rf_init_al2230(struct zd_rf *rf)
424 struct zd_chip *chip = zd_rf_to_chip(rf); 424 struct zd_chip *chip = zd_rf_to_chip(rf);
425 425
426 rf->switch_radio_off = al2230_switch_radio_off; 426 rf->switch_radio_off = al2230_switch_radio_off;
427 if (chip->is_zd1211b) { 427 if (zd_chip_is_zd1211b(chip)) {
428 rf->init_hw = zd1211b_al2230_init_hw; 428 rf->init_hw = zd1211b_al2230_init_hw;
429 rf->set_channel = zd1211b_al2230_set_channel; 429 rf->set_channel = zd1211b_al2230_set_channel;
430 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 180dbcb55f64..a1a54748ccbd 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -196,26 +196,27 @@ static u16 get_word(const void *data, u16 offset)
196 return le16_to_cpu(p[offset]); 196 return le16_to_cpu(p[offset]);
197} 197}
198 198
199static 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,
200 const char* postfix) 200 const char* postfix)
201{ 201{
202 scnprintf(buffer, size, "%s%s", 202 scnprintf(buffer, size, "%s%s",
203 device_type == DEVICE_ZD1211B ? 203 usb->is_zd1211b ?
204 FW_ZD1211B_PREFIX : FW_ZD1211_PREFIX, 204 FW_ZD1211B_PREFIX : FW_ZD1211_PREFIX,
205 postfix); 205 postfix);
206 return buffer; 206 return buffer;
207} 207}
208 208
209static int handle_version_mismatch(struct usb_device *udev, u8 device_type, 209static int handle_version_mismatch(struct zd_usb *usb,
210 const struct firmware *ub_fw) 210 const struct firmware *ub_fw)
211{ 211{
212 struct usb_device *udev = zd_usb_to_usbdev(usb);
212 const struct firmware *ur_fw = NULL; 213 const struct firmware *ur_fw = NULL;
213 int offset; 214 int offset;
214 int r = 0; 215 int r = 0;
215 char fw_name[128]; 216 char fw_name[128];
216 217
217 r = request_fw_file(&ur_fw, 218 r = request_fw_file(&ur_fw,
218 get_fw_name(fw_name, sizeof(fw_name), device_type, "ur"), 219 get_fw_name(usb, fw_name, sizeof(fw_name), "ur"),
219 &udev->dev); 220 &udev->dev);
220 if (r) 221 if (r)
221 goto error; 222 goto error;
@@ -238,11 +239,12 @@ error:
238 return r; 239 return r;
239} 240}
240 241
241static int upload_firmware(struct usb_device *udev, u8 device_type) 242static int upload_firmware(struct zd_usb *usb)
242{ 243{
243 int r; 244 int r;
244 u16 fw_bcdDevice; 245 u16 fw_bcdDevice;
245 u16 bcdDevice; 246 u16 bcdDevice;
247 struct usb_device *udev = zd_usb_to_usbdev(usb);
246 const struct firmware *ub_fw = NULL; 248 const struct firmware *ub_fw = NULL;
247 const struct firmware *uph_fw = NULL; 249 const struct firmware *uph_fw = NULL;
248 char fw_name[128]; 250 char fw_name[128];
@@ -250,7 +252,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
250 bcdDevice = get_bcdDevice(udev); 252 bcdDevice = get_bcdDevice(udev);
251 253
252 r = request_fw_file(&ub_fw, 254 r = request_fw_file(&ub_fw,
253 get_fw_name(fw_name, sizeof(fw_name), device_type, "ub"), 255 get_fw_name(usb, fw_name, sizeof(fw_name), "ub"),
254 &udev->dev); 256 &udev->dev);
255 if (r) 257 if (r)
256 goto error; 258 goto error;
@@ -265,7 +267,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
265 dev_warn(&udev->dev, "device has old bootcode, please " 267 dev_warn(&udev->dev, "device has old bootcode, please "
266 "report success or failure\n"); 268 "report success or failure\n");
267 269
268 r = handle_version_mismatch(udev, device_type, ub_fw); 270 r = handle_version_mismatch(usb, ub_fw);
269 if (r) 271 if (r)
270 goto error; 272 goto error;
271 } else { 273 } else {
@@ -276,7 +278,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
276 278
277 279
278 r = request_fw_file(&uph_fw, 280 r = request_fw_file(&uph_fw,
279 get_fw_name(fw_name, sizeof(fw_name), device_type, "uphr"), 281 get_fw_name(usb, fw_name, sizeof(fw_name), "uphr"),
280 &udev->dev); 282 &udev->dev);
281 if (r) 283 if (r)
282 goto error; 284 goto error;
@@ -295,6 +297,30 @@ error:
295 return r; 297 return r;
296} 298}
297 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
298#define urb_dev(urb) (&(urb)->dev->dev) 324#define urb_dev(urb) (&(urb)->dev->dev)
299 325
300static inline void handle_regs_int(struct urb *urb) 326static inline void handle_regs_int(struct urb *urb)
@@ -921,9 +947,42 @@ static int eject_installer(struct usb_interface *intf)
921 return 0; 947 return 0;
922} 948}
923 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
924static 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)
925{ 983{
926 int r; 984 int r;
985 struct zd_usb *usb;
927 struct usb_device *udev = interface_to_usbdev(intf); 986 struct usb_device *udev = interface_to_usbdev(intf);
928 struct net_device *netdev = NULL; 987 struct net_device *netdev = NULL;
929 988
@@ -951,26 +1010,10 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id)
951 goto error; 1010 goto error;
952 } 1011 }
953 1012
954 r = upload_firmware(udev, id->driver_info); 1013 usb = &zd_netdev_mac(netdev)->chip.usb;
955 if (r) { 1014 usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0;
956 dev_err(&intf->dev,
957 "couldn't load firmware. Error number %d\n", r);
958 goto error;
959 }
960 1015
961 r = usb_reset_configuration(udev); 1016 r = zd_mac_preinit_hw(zd_netdev_mac(netdev));
962 if (r) {
963 dev_dbg_f(&intf->dev,
964 "couldn't reset configuration. Error number %d\n", r);
965 goto error;
966 }
967
968 /* At this point the interrupt endpoint is not generally enabled. We
969 * save the USB bandwidth until the network device is opened. But
970 * notify that the initialization of the MAC will require the
971 * interrupts to be temporary enabled.
972 */
973 r = zd_mac_init_hw(zd_netdev_mac(netdev), id->driver_info);
974 if (r) { 1017 if (r) {
975 dev_dbg_f(&intf->dev, 1018 dev_dbg_f(&intf->dev,
976 "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 */