diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index a49c3d73ea2c..832006b5aab1 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -229,6 +229,31 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer) | |||
229 | /* | 229 | /* |
230 | * Firmware functions | 230 | * Firmware functions |
231 | */ | 231 | */ |
232 | static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev) | ||
233 | { | ||
234 | __le32 *reg; | ||
235 | u32 fw_mode; | ||
236 | |||
237 | reg = kmalloc(sizeof(*reg), GFP_KERNEL); | ||
238 | if (reg == NULL) | ||
239 | return -ENOMEM; | ||
240 | /* cannot use rt2x00usb_register_read here as it uses different | ||
241 | * mode (MULTI_READ vs. DEVICE_MODE) and does not pass the | ||
242 | * magic value USB_MODE_AUTORUN (0x11) to the device, thus the | ||
243 | * returned value would be invalid. | ||
244 | */ | ||
245 | rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE, | ||
246 | USB_VENDOR_REQUEST_IN, 0, USB_MODE_AUTORUN, | ||
247 | reg, sizeof(*reg), REGISTER_TIMEOUT_FIRMWARE); | ||
248 | fw_mode = le32_to_cpu(*reg); | ||
249 | kfree(reg); | ||
250 | |||
251 | if ((fw_mode & 0x00000003) == 2) | ||
252 | return 1; | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
232 | static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 257 | static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) |
233 | { | 258 | { |
234 | return FIRMWARE_RT2870; | 259 | return FIRMWARE_RT2870; |
@@ -240,6 +265,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
240 | int status; | 265 | int status; |
241 | u32 offset; | 266 | u32 offset; |
242 | u32 length; | 267 | u32 length; |
268 | int retval; | ||
243 | 269 | ||
244 | /* | 270 | /* |
245 | * Check which section of the firmware we need. | 271 | * Check which section of the firmware we need. |
@@ -257,8 +283,16 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
257 | /* | 283 | /* |
258 | * Write firmware to device. | 284 | * Write firmware to device. |
259 | */ | 285 | */ |
260 | rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | 286 | retval = rt2800usb_autorun_detect(rt2x00dev); |
261 | data + offset, length); | 287 | if (retval < 0) |
288 | return retval; | ||
289 | if (retval) { | ||
290 | rt2x00_info(rt2x00dev, | ||
291 | "Firmware loading not required - NIC in AutoRun mode\n"); | ||
292 | } else { | ||
293 | rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | ||
294 | data + offset, length); | ||
295 | } | ||
262 | 296 | ||
263 | rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); | 297 | rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); |
264 | rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); | 298 | rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); |
@@ -735,11 +769,26 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
735 | /* | 769 | /* |
736 | * Device probe functions. | 770 | * Device probe functions. |
737 | */ | 771 | */ |
772 | static int rt2800usb_efuse_detect(struct rt2x00_dev *rt2x00dev) | ||
773 | { | ||
774 | int retval; | ||
775 | |||
776 | retval = rt2800usb_autorun_detect(rt2x00dev); | ||
777 | if (retval < 0) | ||
778 | return retval; | ||
779 | if (retval) | ||
780 | return 1; | ||
781 | return rt2800_efuse_detect(rt2x00dev); | ||
782 | } | ||
783 | |||
738 | static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev) | 784 | static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev) |
739 | { | 785 | { |
740 | int retval; | 786 | int retval; |
741 | 787 | ||
742 | if (rt2800_efuse_detect(rt2x00dev)) | 788 | retval = rt2800usb_efuse_detect(rt2x00dev); |
789 | if (retval < 0) | ||
790 | return retval; | ||
791 | if (retval) | ||
743 | retval = rt2800_read_eeprom_efuse(rt2x00dev); | 792 | retval = rt2800_read_eeprom_efuse(rt2x00dev); |
744 | else | 793 | else |
745 | retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, | 794 | retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, |