Loading MAINTAINERS +2 −1 Original line number Diff line number Diff line Loading @@ -1412,7 +1412,7 @@ F: net/ax25/ B43 WIRELESS DRIVER M: Stefano Brivio <stefano.brivio@polimi.it> L: linux-wireless@vger.kernel.org L: b43-dev@lists.infradead.org (moderated for non-subscribers) L: b43-dev@lists.infradead.org W: http://linuxwireless.org/en/users/Drivers/b43 S: Maintained F: drivers/net/wireless/b43/ Loading @@ -1421,6 +1421,7 @@ B43LEGACY WIRELESS DRIVER M: Larry Finger <Larry.Finger@lwfinger.net> M: Stefano Brivio <stefano.brivio@polimi.it> L: linux-wireless@vger.kernel.org L: b43-dev@lists.infradead.org W: http://linuxwireless.org/en/users/Drivers/b43 S: Maintained F: drivers/net/wireless/b43legacy/ Loading drivers/bcma/sprom.c +111 −69 Original line number Diff line number Diff line Loading @@ -14,8 +14,6 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> #define SPOFF(offset) ((offset) / sizeof(u16)) /************************************************** * R/W ops. **************************************************/ Loading Loading @@ -124,10 +122,21 @@ static int bcma_sprom_valid(const u16 *sprom) * SPROM extraction. **************************************************/ #define SPOFF(offset) ((offset) / sizeof(u16)) #define SPEX(_field, _offset, _mask, _shift) \ bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift)) static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) { u16 v; u16 v, o; int i; u16 pwr_info_offset[] = { SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 }; BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != ARRAY_SIZE(bus->sprom.core_pwr_info)); bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV; Loading @@ -137,72 +146,104 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); } bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)]; bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT; bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT; bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT; bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT; bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT; bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT; bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT; bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT; bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT; bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT; bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT; bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT; bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT; bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT; bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT; bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT; bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)]; bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)]; bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)]; bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)]; bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)]; bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0); SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT); SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT); SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT); SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT); SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT); SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT); SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT); SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT); SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT); SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT); SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT); SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT); SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT); SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT); SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT); SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT); SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0); SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0); SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0); SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0); SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0); /* Extract cores power info info */ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { o = pwr_info_offset[i]; SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, SSB_SPROM8_2G_MAXP, 0); SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, SSB_SPROM8_5G_MAXP, 0); SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, SSB_SPROM8_5GH_MAXP, 0); SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); } SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT); SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT); SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT); SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT); SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); } int bcma_sprom_get(struct bcma_bus *bus) Loading Loading @@ -230,6 +271,7 @@ int bcma_sprom_get(struct bcma_bus *bus) * TODO: understand this condition and use it */ offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : BCMA_CC_SPROM_PCIE6; pr_debug("SPROM offset 0x%x\n", offset); bcma_sprom_read(bus, offset, sprom); if (bus->chipinfo.id == 0x4331) Loading drivers/net/wireless/ath/ath5k/base.c +4 −1 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ static bool modparam_fastchanswitch; module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); static int ath5k_modparam_no_hw_rfkill_switch; static bool ath5k_modparam_no_hw_rfkill_switch; module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch, bool, S_IRUGO); MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state"); Loading Loading @@ -2442,6 +2442,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); /* SW support for IBSS_RSN is provided by mac80211 */ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; /* both antennas can be configured as RX or TX */ hw->wiphy->available_antennas_tx = 0x3; hw->wiphy->available_antennas_rx = 0x3; Loading drivers/net/wireless/ath/ath5k/mac80211-ops.c +8 −0 Original line number Diff line number Diff line Loading @@ -483,6 +483,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ath5k_modparam_nohwcrypt) return -EOPNOTSUPP; if (vif->type == NL80211_IFTYPE_ADHOC && (key->cipher == WLAN_CIPHER_SUITE_TKIP || key->cipher == WLAN_CIPHER_SUITE_CCMP) && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { /* don't program group keys when using IBSS_RSN */ return -EOPNOTSUPP; } switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: Loading drivers/net/wireless/ath/ath9k/hif_usb.c +99 −55 Original line number Diff line number Diff line Loading @@ -968,8 +968,7 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) ath9k_hif_usb_dealloc_rx_urbs(hif_dev); } static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, u32 drv_info) static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) { int transfer, err; const void *data = hif_dev->firmware->data; Loading Loading @@ -1000,7 +999,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, } kfree(buf); if (IS_AR7010_DEVICE(drv_info)) if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info)) firm_offset = AR7010_FIRMWARE_TEXT; else firm_offset = AR9271_FIRMWARE_TEXT; Loading @@ -1021,28 +1020,18 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, return 0; } static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { int ret, idx; struct usb_host_interface *alt = &hif_dev->interface->altsetting[0]; struct usb_endpoint_descriptor *endp; int ret, idx; /* Request firmware */ ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name, &hif_dev->udev->dev); if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name); goto err_fw_req; } /* Download firmware */ ret = ath9k_hif_usb_download_fw(hif_dev, drv_info); ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Firmware - %s download failed\n", hif_dev->fw_name); goto err_fw_download; return ret; } /* On downloading the firmware to the target, the USB descriptor of EP4 Loading @@ -1064,23 +1053,84 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Unable to allocate URBs\n"); goto err_fw_download; return ret; } return 0; err_fw_download: release_firmware(hif_dev->firmware); err_fw_req: hif_dev->firmware = NULL; return ret; } static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev) { ath9k_hif_usb_dealloc_urbs(hif_dev); if (hif_dev->firmware) release_firmware(hif_dev->firmware); } /* * If initialization fails or the FW cannot be retrieved, * detach the device. */ static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev) { struct device *parent = hif_dev->udev->dev.parent; complete(&hif_dev->fw_done); if (parent) device_lock(parent); device_release_driver(&hif_dev->udev->dev); if (parent) device_unlock(parent); } static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) { struct hif_device_usb *hif_dev = context; int ret; if (!fw) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Failed to get firmware %s\n", hif_dev->fw_name); goto err_fw; } hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, &hif_dev->udev->dev); if (hif_dev->htc_handle == NULL) { goto err_fw; } hif_dev->firmware = fw; /* Proceed with initialization */ ret = ath9k_hif_usb_dev_init(hif_dev); if (ret) goto err_dev_init; ret = ath9k_htc_hw_init(hif_dev->htc_handle, &hif_dev->interface->dev, hif_dev->usb_device_id->idProduct, hif_dev->udev->product, hif_dev->usb_device_id->driver_info); if (ret) { ret = -EINVAL; goto err_htc_hw_init; } complete(&hif_dev->fw_done); return; err_htc_hw_init: ath9k_hif_usb_dev_deinit(hif_dev); err_dev_init: ath9k_htc_hw_free(hif_dev->htc_handle); release_firmware(fw); hif_dev->firmware = NULL; err_fw: ath9k_hif_usb_firmware_fail(hif_dev); } /* Loading Loading @@ -1155,20 +1205,16 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, } usb_get_dev(udev); hif_dev->udev = udev; hif_dev->interface = interface; hif_dev->device_id = id->idProduct; hif_dev->usb_device_id = id; #ifdef CONFIG_PM udev->reset_resume = 1; #endif usb_set_intfdata(interface, hif_dev); hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, &hif_dev->udev->dev); if (hif_dev->htc_handle == NULL) { ret = -ENOMEM; goto err_htc_hw_alloc; } init_completion(&hif_dev->fw_done); /* Find out which firmware to load */ Loading @@ -1177,29 +1223,22 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, else hif_dev->fw_name = FIRMWARE_AR9271; ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info); ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name, &hif_dev->udev->dev, GFP_KERNEL, hif_dev, ath9k_hif_usb_firmware_cb); if (ret) { ret = -EINVAL; goto err_hif_init_usb; } ret = ath9k_htc_hw_init(hif_dev->htc_handle, &interface->dev, hif_dev->device_id, hif_dev->udev->product, id->driver_info); if (ret) { ret = -EINVAL; goto err_htc_hw_init; dev_err(&hif_dev->udev->dev, "ath9k_htc: Async request for firmware %s failed\n", hif_dev->fw_name); goto err_fw_req; } dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n"); dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", hif_dev->fw_name); return 0; err_htc_hw_init: ath9k_hif_usb_dev_deinit(hif_dev); err_hif_init_usb: ath9k_htc_hw_free(hif_dev->htc_handle); err_htc_hw_alloc: err_fw_req: usb_set_intfdata(interface, NULL); kfree(hif_dev); usb_put_dev(udev); Loading Loading @@ -1234,9 +1273,15 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) if (!hif_dev) return; wait_for_completion(&hif_dev->fw_done); if (hif_dev->firmware) { ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); ath9k_htc_hw_free(hif_dev->htc_handle); ath9k_hif_usb_dev_deinit(hif_dev); release_firmware(hif_dev->firmware); } usb_set_intfdata(interface, NULL); if (!unplugged && (hif_dev->flags & HIF_USB_START)) Loading Loading @@ -1276,8 +1321,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) return ret; if (hif_dev->firmware) { ret = ath9k_hif_usb_download_fw(hif_dev, htc_handle->drv_priv->ah->hw_version.usbdev); ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) goto fail_resume; } else { Loading Loading
MAINTAINERS +2 −1 Original line number Diff line number Diff line Loading @@ -1412,7 +1412,7 @@ F: net/ax25/ B43 WIRELESS DRIVER M: Stefano Brivio <stefano.brivio@polimi.it> L: linux-wireless@vger.kernel.org L: b43-dev@lists.infradead.org (moderated for non-subscribers) L: b43-dev@lists.infradead.org W: http://linuxwireless.org/en/users/Drivers/b43 S: Maintained F: drivers/net/wireless/b43/ Loading @@ -1421,6 +1421,7 @@ B43LEGACY WIRELESS DRIVER M: Larry Finger <Larry.Finger@lwfinger.net> M: Stefano Brivio <stefano.brivio@polimi.it> L: linux-wireless@vger.kernel.org L: b43-dev@lists.infradead.org W: http://linuxwireless.org/en/users/Drivers/b43 S: Maintained F: drivers/net/wireless/b43legacy/ Loading
drivers/bcma/sprom.c +111 −69 Original line number Diff line number Diff line Loading @@ -14,8 +14,6 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> #define SPOFF(offset) ((offset) / sizeof(u16)) /************************************************** * R/W ops. **************************************************/ Loading Loading @@ -124,10 +122,21 @@ static int bcma_sprom_valid(const u16 *sprom) * SPROM extraction. **************************************************/ #define SPOFF(offset) ((offset) / sizeof(u16)) #define SPEX(_field, _offset, _mask, _shift) \ bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift)) static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) { u16 v; u16 v, o; int i; u16 pwr_info_offset[] = { SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 }; BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != ARRAY_SIZE(bus->sprom.core_pwr_info)); bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV; Loading @@ -137,72 +146,104 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); } bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)]; bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT; bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT; bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT; bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT; bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT; bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT; bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT; bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT; bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT; bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT; bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT; bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT; bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT; bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT; bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT; bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT; bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)]; bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)]; bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)]; bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)]; bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)]; bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0); SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT); SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT); SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT); SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT); SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT); SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT); SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT); SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT); SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT); SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT); SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT); SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT); SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT); SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT); SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT); SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT); SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0); SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0); SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0); SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0); SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0); /* Extract cores power info info */ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { o = pwr_info_offset[i]; SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, SSB_SPROM8_2G_MAXP, 0); SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, SSB_SPROM8_5G_MAXP, 0); SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, SSB_SPROM8_5GH_MAXP, 0); SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); } SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT); SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT); SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT); SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT); SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); } int bcma_sprom_get(struct bcma_bus *bus) Loading Loading @@ -230,6 +271,7 @@ int bcma_sprom_get(struct bcma_bus *bus) * TODO: understand this condition and use it */ offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : BCMA_CC_SPROM_PCIE6; pr_debug("SPROM offset 0x%x\n", offset); bcma_sprom_read(bus, offset, sprom); if (bus->chipinfo.id == 0x4331) Loading
drivers/net/wireless/ath/ath5k/base.c +4 −1 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ static bool modparam_fastchanswitch; module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); static int ath5k_modparam_no_hw_rfkill_switch; static bool ath5k_modparam_no_hw_rfkill_switch; module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch, bool, S_IRUGO); MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state"); Loading Loading @@ -2442,6 +2442,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); /* SW support for IBSS_RSN is provided by mac80211 */ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; /* both antennas can be configured as RX or TX */ hw->wiphy->available_antennas_tx = 0x3; hw->wiphy->available_antennas_rx = 0x3; Loading
drivers/net/wireless/ath/ath5k/mac80211-ops.c +8 −0 Original line number Diff line number Diff line Loading @@ -483,6 +483,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ath5k_modparam_nohwcrypt) return -EOPNOTSUPP; if (vif->type == NL80211_IFTYPE_ADHOC && (key->cipher == WLAN_CIPHER_SUITE_TKIP || key->cipher == WLAN_CIPHER_SUITE_CCMP) && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { /* don't program group keys when using IBSS_RSN */ return -EOPNOTSUPP; } switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: Loading
drivers/net/wireless/ath/ath9k/hif_usb.c +99 −55 Original line number Diff line number Diff line Loading @@ -968,8 +968,7 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) ath9k_hif_usb_dealloc_rx_urbs(hif_dev); } static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, u32 drv_info) static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) { int transfer, err; const void *data = hif_dev->firmware->data; Loading Loading @@ -1000,7 +999,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, } kfree(buf); if (IS_AR7010_DEVICE(drv_info)) if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info)) firm_offset = AR7010_FIRMWARE_TEXT; else firm_offset = AR9271_FIRMWARE_TEXT; Loading @@ -1021,28 +1020,18 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, return 0; } static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { int ret, idx; struct usb_host_interface *alt = &hif_dev->interface->altsetting[0]; struct usb_endpoint_descriptor *endp; int ret, idx; /* Request firmware */ ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name, &hif_dev->udev->dev); if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name); goto err_fw_req; } /* Download firmware */ ret = ath9k_hif_usb_download_fw(hif_dev, drv_info); ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Firmware - %s download failed\n", hif_dev->fw_name); goto err_fw_download; return ret; } /* On downloading the firmware to the target, the USB descriptor of EP4 Loading @@ -1064,23 +1053,84 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Unable to allocate URBs\n"); goto err_fw_download; return ret; } return 0; err_fw_download: release_firmware(hif_dev->firmware); err_fw_req: hif_dev->firmware = NULL; return ret; } static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev) { ath9k_hif_usb_dealloc_urbs(hif_dev); if (hif_dev->firmware) release_firmware(hif_dev->firmware); } /* * If initialization fails or the FW cannot be retrieved, * detach the device. */ static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev) { struct device *parent = hif_dev->udev->dev.parent; complete(&hif_dev->fw_done); if (parent) device_lock(parent); device_release_driver(&hif_dev->udev->dev); if (parent) device_unlock(parent); } static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) { struct hif_device_usb *hif_dev = context; int ret; if (!fw) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Failed to get firmware %s\n", hif_dev->fw_name); goto err_fw; } hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, &hif_dev->udev->dev); if (hif_dev->htc_handle == NULL) { goto err_fw; } hif_dev->firmware = fw; /* Proceed with initialization */ ret = ath9k_hif_usb_dev_init(hif_dev); if (ret) goto err_dev_init; ret = ath9k_htc_hw_init(hif_dev->htc_handle, &hif_dev->interface->dev, hif_dev->usb_device_id->idProduct, hif_dev->udev->product, hif_dev->usb_device_id->driver_info); if (ret) { ret = -EINVAL; goto err_htc_hw_init; } complete(&hif_dev->fw_done); return; err_htc_hw_init: ath9k_hif_usb_dev_deinit(hif_dev); err_dev_init: ath9k_htc_hw_free(hif_dev->htc_handle); release_firmware(fw); hif_dev->firmware = NULL; err_fw: ath9k_hif_usb_firmware_fail(hif_dev); } /* Loading Loading @@ -1155,20 +1205,16 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, } usb_get_dev(udev); hif_dev->udev = udev; hif_dev->interface = interface; hif_dev->device_id = id->idProduct; hif_dev->usb_device_id = id; #ifdef CONFIG_PM udev->reset_resume = 1; #endif usb_set_intfdata(interface, hif_dev); hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, &hif_dev->udev->dev); if (hif_dev->htc_handle == NULL) { ret = -ENOMEM; goto err_htc_hw_alloc; } init_completion(&hif_dev->fw_done); /* Find out which firmware to load */ Loading @@ -1177,29 +1223,22 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, else hif_dev->fw_name = FIRMWARE_AR9271; ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info); ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name, &hif_dev->udev->dev, GFP_KERNEL, hif_dev, ath9k_hif_usb_firmware_cb); if (ret) { ret = -EINVAL; goto err_hif_init_usb; } ret = ath9k_htc_hw_init(hif_dev->htc_handle, &interface->dev, hif_dev->device_id, hif_dev->udev->product, id->driver_info); if (ret) { ret = -EINVAL; goto err_htc_hw_init; dev_err(&hif_dev->udev->dev, "ath9k_htc: Async request for firmware %s failed\n", hif_dev->fw_name); goto err_fw_req; } dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n"); dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", hif_dev->fw_name); return 0; err_htc_hw_init: ath9k_hif_usb_dev_deinit(hif_dev); err_hif_init_usb: ath9k_htc_hw_free(hif_dev->htc_handle); err_htc_hw_alloc: err_fw_req: usb_set_intfdata(interface, NULL); kfree(hif_dev); usb_put_dev(udev); Loading Loading @@ -1234,9 +1273,15 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) if (!hif_dev) return; wait_for_completion(&hif_dev->fw_done); if (hif_dev->firmware) { ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); ath9k_htc_hw_free(hif_dev->htc_handle); ath9k_hif_usb_dev_deinit(hif_dev); release_firmware(hif_dev->firmware); } usb_set_intfdata(interface, NULL); if (!unplugged && (hif_dev->flags & HIF_USB_START)) Loading Loading @@ -1276,8 +1321,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) return ret; if (hif_dev->firmware) { ret = ath9k_hif_usb_download_fw(hif_dev, htc_handle->drv_priv->ah->hw_version.usbdev); ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) goto fail_resume; } else { Loading