aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw/zd_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_usb.c')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c98
1 files changed, 71 insertions, 27 deletions
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);