diff options
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 88 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 59 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf_al2230.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf_al7230b.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf_rf2959.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf_uw2453.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 98 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.h | 3 |
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 | ||
52 | static int scnprint_mac_oui(const u8 *addr, char *buffer, size_t size) | 52 | static 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 | ||
369 | static 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 | |||
392 | static 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 | */ |
403 | void 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 | |||
410 | static 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 | |||
416 | int 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 | |||
427 | int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) | 373 | int 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 | ||
810 | static int hw_reset_phy(struct zd_chip *chip) | 750 | static 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 */ | ||
1080 | int 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 | ||
1140 | int zd_chip_init_hw(struct zd_chip *chip, u8 device_type) | 1087 | int 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 | ||
721 | static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb) | 720 | static 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); |
736 | void zd_chip_clear(struct zd_chip *chip); | 735 | void zd_chip_clear(struct zd_chip *chip); |
737 | int zd_chip_init_hw(struct zd_chip *chip, u8 device_type); | 736 | int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr); |
737 | int zd_chip_init_hw(struct zd_chip *chip); | ||
738 | int zd_chip_reset(struct zd_chip *chip); | 738 | int zd_chip_reset(struct zd_chip *chip); |
739 | 739 | ||
740 | static inline int zd_chip_is_zd1211b(struct zd_chip *chip) | ||
741 | { | ||
742 | return chip->usb.is_zd1211b; | ||
743 | } | ||
744 | |||
740 | static inline int zd_ioread16v_locked(struct zd_chip *chip, u16 *values, | 745 | static 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 | } |
826 | u8 zd_chip_get_channel(struct zd_chip *chip); | 831 | u8 zd_chip_get_channel(struct zd_chip *chip); |
827 | int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain); | 832 | int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain); |
828 | void zd_get_e2p_mac_addr(struct zd_chip *chip, u8 *mac_addr); | ||
829 | int zd_read_mac_addr(struct zd_chip *chip, u8 *mac_addr); | ||
830 | int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr); | 833 | int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr); |
831 | int zd_chip_switch_radio_on(struct zd_chip *chip); | 834 | int zd_chip_switch_radio_on(struct zd_chip *chip); |
832 | int zd_chip_switch_radio_off(struct zd_chip *chip); | 835 | int 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 | ||
89 | int zd_mac_init_hw(struct zd_mac *mac, u8 device_type) | 89 | int 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 | |||
102 | int 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); |
190 | void zd_mac_clear(struct zd_mac *mac); | 190 | void zd_mac_clear(struct zd_mac *mac); |
191 | 191 | ||
192 | int zd_mac_init_hw(struct zd_mac *mac, u8 device_type); | 192 | int zd_mac_preinit_hw(struct zd_mac *mac); |
193 | int zd_mac_init_hw(struct zd_mac *mac); | ||
193 | 194 | ||
194 | int zd_mac_open(struct net_device *netdev); | 195 | int zd_mac_open(struct net_device *netdev); |
195 | int zd_mac_stop(struct net_device *netdev); | 196 | int 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 | |||
24 | static const u32 zd1211_al2230_table[][3] = { | 26 | static 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 740a2194fdde..a1a54748ccbd 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 | ||
198 | static char *get_fw_name(char *buffer, size_t size, u8 device_type, | 199 | static 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 | ||
208 | static int handle_version_mismatch(struct usb_device *udev, u8 device_type, | 209 | static 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 | ||
240 | static int upload_firmware(struct usb_device *udev, u8 device_type) | 242 | static 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. */ | ||
302 | int 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 | ||
299 | static inline void handle_regs_int(struct urb *urb) | 326 | static 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 | ||
950 | int 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 | |||
923 | static int probe(struct usb_interface *intf, const struct usb_device_id *id) | 982 | static 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 | ||
237 | int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits); | 238 | int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits); |
238 | 239 | ||
240 | int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len); | ||
241 | |||
239 | extern struct workqueue_struct *zd_workqueue; | 242 | extern struct workqueue_struct *zd_workqueue; |
240 | 243 | ||
241 | #endif /* _ZD_USB_H */ | 244 | #endif /* _ZD_USB_H */ |