aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2007-07-01 13:22:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-07-10 14:14:56 -0400
commit74553aedd46b3a2cae986f909cf2a3f99369decc (patch)
tree6904945b36c017c58249b1900fbbd531f3286e49 /drivers/net
parent93f510bbac64f552ef6872a39ae12afa06c4e999 (diff)
[PATCH] zd1211rw: Defer firmware load until first ifup
While playing with the firmware a while back, I discovered a way to access the device's entire address space before the firmware has been loaded. Previously we were loading the firmware early on (during probe) so that we could read the MAC address from the EEPROM and register a netdevice. Now that we can read the EEPROM without having firmware, we can defer firmware loading until later while still reading the MAC address early on. This has the advantage that zd1211rw can now be built into the kernel -- previously if this was the case, zd1211rw would be loaded before the filesystem is available and firmware loading would fail. Firmware load and other device initialization operations now happen the first time the interface is brought up. Some architectural changes were needed: handling of the is_zd1211b flag was moved into the zd_usb structure, MAC address handling was obviously changed, and a preinit_hw stage was added (the order is now: init, preinit_hw, init_hw). Signed-off-by: Daniel Drake <dsd@gentoo.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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 5b624bfc01a..c39f1984b84 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 79d0288c193..f4698576ab7 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 522de3f0dfa..f6c487aa824 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 faf4c7828d4..9f9344eb50f 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 be9259eea08..006774de320 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 f4e8b6ada85..73d0bb26f81 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 2d736bdf707..cc70d40684e 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 414e40d571a..857dcf3eae6 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 180dbcb55f6..a1a54748ccb 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 506ea6a7439..961a7a12ad6 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 */