diff options
Diffstat (limited to 'drivers/net/wireless')
20 files changed, 529 insertions, 435 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h index 28fd99203f64..bdee2ed67219 100644 --- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h | |||
| @@ -519,7 +519,7 @@ static const u32 ar9580_1p0_mac_core[][2] = { | |||
| 519 | {0x00008258, 0x00000000}, | 519 | {0x00008258, 0x00000000}, |
| 520 | {0x0000825c, 0x40000000}, | 520 | {0x0000825c, 0x40000000}, |
| 521 | {0x00008260, 0x00080922}, | 521 | {0x00008260, 0x00080922}, |
| 522 | {0x00008264, 0x9bc00010}, | 522 | {0x00008264, 0x9d400010}, |
| 523 | {0x00008268, 0xffffffff}, | 523 | {0x00008268, 0xffffffff}, |
| 524 | {0x0000826c, 0x0000ffff}, | 524 | {0x0000826c, 0x0000ffff}, |
| 525 | {0x00008270, 0x00000000}, | 525 | {0x00008270, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c index 467b60014b7b..73fe8d6db566 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c | |||
| @@ -143,14 +143,14 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) | |||
| 143 | u32 sz, i; | 143 | u32 sz, i; |
| 144 | struct channel_detector *cd; | 144 | struct channel_detector *cd; |
| 145 | 145 | ||
| 146 | cd = kmalloc(sizeof(*cd), GFP_KERNEL); | 146 | cd = kmalloc(sizeof(*cd), GFP_ATOMIC); |
| 147 | if (cd == NULL) | 147 | if (cd == NULL) |
| 148 | goto fail; | 148 | goto fail; |
| 149 | 149 | ||
| 150 | INIT_LIST_HEAD(&cd->head); | 150 | INIT_LIST_HEAD(&cd->head); |
| 151 | cd->freq = freq; | 151 | cd->freq = freq; |
| 152 | sz = sizeof(cd->detectors) * dpd->num_radar_types; | 152 | sz = sizeof(cd->detectors) * dpd->num_radar_types; |
| 153 | cd->detectors = kzalloc(sz, GFP_KERNEL); | 153 | cd->detectors = kzalloc(sz, GFP_ATOMIC); |
| 154 | if (cd->detectors == NULL) | 154 | if (cd->detectors == NULL) |
| 155 | goto fail; | 155 | goto fail; |
| 156 | 156 | ||
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c index 91b8dceeadb1..5e48c5515b8c 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c | |||
| @@ -218,7 +218,7 @@ static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts) | |||
| 218 | { | 218 | { |
| 219 | struct pulse_elem *p = pool_get_pulse_elem(); | 219 | struct pulse_elem *p = pool_get_pulse_elem(); |
| 220 | if (p == NULL) { | 220 | if (p == NULL) { |
| 221 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 221 | p = kmalloc(sizeof(*p), GFP_ATOMIC); |
| 222 | if (p == NULL) { | 222 | if (p == NULL) { |
| 223 | DFS_POOL_STAT_INC(pulse_alloc_error); | 223 | DFS_POOL_STAT_INC(pulse_alloc_error); |
| 224 | return false; | 224 | return false; |
| @@ -299,7 +299,7 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde, | |||
| 299 | ps.deadline_ts = ps.first_ts + ps.dur; | 299 | ps.deadline_ts = ps.first_ts + ps.dur; |
| 300 | new_ps = pool_get_pseq_elem(); | 300 | new_ps = pool_get_pseq_elem(); |
| 301 | if (new_ps == NULL) { | 301 | if (new_ps == NULL) { |
| 302 | new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL); | 302 | new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC); |
| 303 | if (new_ps == NULL) { | 303 | if (new_ps == NULL) { |
| 304 | DFS_POOL_STAT_INC(pseq_alloc_error); | 304 | DFS_POOL_STAT_INC(pseq_alloc_error); |
| 305 | return false; | 305 | return false; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 716058b67557..a47f5e05fc04 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
| @@ -796,7 +796,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) | |||
| 796 | * required version. | 796 | * required version. |
| 797 | */ | 797 | */ |
| 798 | if (priv->fw_version_major != MAJOR_VERSION_REQ || | 798 | if (priv->fw_version_major != MAJOR_VERSION_REQ || |
| 799 | priv->fw_version_minor != MINOR_VERSION_REQ) { | 799 | priv->fw_version_minor < MINOR_VERSION_REQ) { |
| 800 | dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", | 800 | dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", |
| 801 | MAJOR_VERSION_REQ, MINOR_VERSION_REQ); | 801 | MAJOR_VERSION_REQ, MINOR_VERSION_REQ); |
| 802 | return -EINVAL; | 802 | return -EINVAL; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6e66f9c6782b..988372d218a4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -280,6 +280,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
| 280 | if (r) { | 280 | if (r) { |
| 281 | ath_err(common, | 281 | ath_err(common, |
| 282 | "Unable to reset channel, reset status %d\n", r); | 282 | "Unable to reset channel, reset status %d\n", r); |
| 283 | |||
| 284 | ath9k_hw_enable_interrupts(ah); | ||
| 285 | ath9k_queue_reset(sc, RESET_TYPE_BB_HANG); | ||
| 286 | |||
| 283 | goto out; | 287 | goto out; |
| 284 | } | 288 | } |
| 285 | 289 | ||
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e8486c1e091a..b70f220bc4b3 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
| @@ -5165,7 +5165,8 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) | |||
| 5165 | #endif | 5165 | #endif |
| 5166 | #ifdef CONFIG_B43_SSB | 5166 | #ifdef CONFIG_B43_SSB |
| 5167 | case B43_BUS_SSB: | 5167 | case B43_BUS_SSB: |
| 5168 | /* FIXME */ | 5168 | ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco, |
| 5169 | avoid); | ||
| 5169 | break; | 5170 | break; |
| 5170 | #endif | 5171 | #endif |
| 5171 | } | 5172 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 4469321c0eb3..35fc68be158d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
| @@ -3317,15 +3317,15 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) | |||
| 3317 | goto err; | 3317 | goto err; |
| 3318 | } | 3318 | } |
| 3319 | 3319 | ||
| 3320 | /* External image takes precedence if specified */ | ||
| 3321 | if (brcmf_sdbrcm_download_code_file(bus)) { | 3320 | if (brcmf_sdbrcm_download_code_file(bus)) { |
| 3322 | brcmf_err("dongle image file download failed\n"); | 3321 | brcmf_err("dongle image file download failed\n"); |
| 3323 | goto err; | 3322 | goto err; |
| 3324 | } | 3323 | } |
| 3325 | 3324 | ||
| 3326 | /* External nvram takes precedence if specified */ | 3325 | if (brcmf_sdbrcm_download_nvram(bus)) { |
| 3327 | if (brcmf_sdbrcm_download_nvram(bus)) | ||
| 3328 | brcmf_err("dongle nvram file download failed\n"); | 3326 | brcmf_err("dongle nvram file download failed\n"); |
| 3327 | goto err; | ||
| 3328 | } | ||
| 3329 | 3329 | ||
| 3330 | /* Take arm out of reset */ | 3330 | /* Take arm out of reset */ |
| 3331 | if (brcmf_sdbrcm_download_state(bus, false)) { | 3331 | if (brcmf_sdbrcm_download_state(bus, false)) { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 2af9c0f0798d..78da3eff75e8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
| @@ -1891,8 +1891,10 @@ static s32 | |||
| 1891 | brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, | 1891 | brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, |
| 1892 | u8 key_idx, const u8 *mac_addr, struct key_params *params) | 1892 | u8 key_idx, const u8 *mac_addr, struct key_params *params) |
| 1893 | { | 1893 | { |
| 1894 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 1894 | struct brcmf_wsec_key key; | 1895 | struct brcmf_wsec_key key; |
| 1895 | s32 err = 0; | 1896 | s32 err = 0; |
| 1897 | u8 keybuf[8]; | ||
| 1896 | 1898 | ||
| 1897 | memset(&key, 0, sizeof(key)); | 1899 | memset(&key, 0, sizeof(key)); |
| 1898 | key.index = (u32) key_idx; | 1900 | key.index = (u32) key_idx; |
| @@ -1916,8 +1918,9 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, | |||
| 1916 | brcmf_dbg(CONN, "Setting the key index %d\n", key.index); | 1918 | brcmf_dbg(CONN, "Setting the key index %d\n", key.index); |
| 1917 | memcpy(key.data, params->key, key.len); | 1919 | memcpy(key.data, params->key, key.len); |
| 1918 | 1920 | ||
| 1919 | if (params->cipher == WLAN_CIPHER_SUITE_TKIP) { | 1921 | if ((ifp->vif->mode != WL_MODE_AP) && |
| 1920 | u8 keybuf[8]; | 1922 | (params->cipher == WLAN_CIPHER_SUITE_TKIP)) { |
| 1923 | brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); | ||
| 1921 | memcpy(keybuf, &key.data[24], sizeof(keybuf)); | 1924 | memcpy(keybuf, &key.data[24], sizeof(keybuf)); |
| 1922 | memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); | 1925 | memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); |
| 1923 | memcpy(&key.data[16], keybuf, sizeof(keybuf)); | 1926 | memcpy(&key.data[16], keybuf, sizeof(keybuf)); |
| @@ -2013,7 +2016,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
| 2013 | break; | 2016 | break; |
| 2014 | case WLAN_CIPHER_SUITE_TKIP: | 2017 | case WLAN_CIPHER_SUITE_TKIP: |
| 2015 | if (ifp->vif->mode != WL_MODE_AP) { | 2018 | if (ifp->vif->mode != WL_MODE_AP) { |
| 2016 | brcmf_dbg(CONN, "Swapping key\n"); | 2019 | brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); |
| 2017 | memcpy(keybuf, &key.data[24], sizeof(keybuf)); | 2020 | memcpy(keybuf, &key.data[24], sizeof(keybuf)); |
| 2018 | memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); | 2021 | memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); |
| 2019 | memcpy(&key.data[16], keybuf, sizeof(keybuf)); | 2022 | memcpy(&key.data[16], keybuf, sizeof(keybuf)); |
| @@ -2118,8 +2121,7 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, | |||
| 2118 | err = -EAGAIN; | 2121 | err = -EAGAIN; |
| 2119 | goto done; | 2122 | goto done; |
| 2120 | } | 2123 | } |
| 2121 | switch (wsec & ~SES_OW_ENABLED) { | 2124 | if (wsec & WEP_ENABLED) { |
| 2122 | case WEP_ENABLED: | ||
| 2123 | sec = &profile->sec; | 2125 | sec = &profile->sec; |
| 2124 | if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { | 2126 | if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { |
| 2125 | params.cipher = WLAN_CIPHER_SUITE_WEP40; | 2127 | params.cipher = WLAN_CIPHER_SUITE_WEP40; |
| @@ -2128,16 +2130,13 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, | |||
| 2128 | params.cipher = WLAN_CIPHER_SUITE_WEP104; | 2130 | params.cipher = WLAN_CIPHER_SUITE_WEP104; |
| 2129 | brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); | 2131 | brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); |
| 2130 | } | 2132 | } |
| 2131 | break; | 2133 | } else if (wsec & TKIP_ENABLED) { |
| 2132 | case TKIP_ENABLED: | ||
| 2133 | params.cipher = WLAN_CIPHER_SUITE_TKIP; | 2134 | params.cipher = WLAN_CIPHER_SUITE_TKIP; |
| 2134 | brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n"); | 2135 | brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n"); |
| 2135 | break; | 2136 | } else if (wsec & AES_ENABLED) { |
| 2136 | case AES_ENABLED: | ||
| 2137 | params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; | 2137 | params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; |
| 2138 | brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); | 2138 | brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); |
| 2139 | break; | 2139 | } else { |
| 2140 | default: | ||
| 2141 | brcmf_err("Invalid algo (0x%x)\n", wsec); | 2140 | brcmf_err("Invalid algo (0x%x)\n", wsec); |
| 2142 | err = -EINVAL; | 2141 | err = -EINVAL; |
| 2143 | goto done; | 2142 | goto done; |
| @@ -3824,8 +3823,9 @@ exit: | |||
| 3824 | static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) | 3823 | static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) |
| 3825 | { | 3824 | { |
| 3826 | struct brcmf_if *ifp = netdev_priv(ndev); | 3825 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 3827 | s32 err = -EPERM; | 3826 | s32 err; |
| 3828 | struct brcmf_fil_bss_enable_le bss_enable; | 3827 | struct brcmf_fil_bss_enable_le bss_enable; |
| 3828 | struct brcmf_join_params join_params; | ||
| 3829 | 3829 | ||
| 3830 | brcmf_dbg(TRACE, "Enter\n"); | 3830 | brcmf_dbg(TRACE, "Enter\n"); |
| 3831 | 3831 | ||
| @@ -3833,16 +3833,21 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) | |||
| 3833 | /* Due to most likely deauths outstanding we sleep */ | 3833 | /* Due to most likely deauths outstanding we sleep */ |
| 3834 | /* first to make sure they get processed by fw. */ | 3834 | /* first to make sure they get processed by fw. */ |
| 3835 | msleep(400); | 3835 | msleep(400); |
| 3836 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0); | 3836 | |
| 3837 | if (err < 0) { | 3837 | memset(&join_params, 0, sizeof(join_params)); |
| 3838 | brcmf_err("setting AP mode failed %d\n", err); | 3838 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, |
| 3839 | goto exit; | 3839 | &join_params, sizeof(join_params)); |
| 3840 | } | 3840 | if (err < 0) |
| 3841 | brcmf_err("SET SSID error (%d)\n", err); | ||
| 3841 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); | 3842 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); |
| 3842 | if (err < 0) { | 3843 | if (err < 0) |
| 3843 | brcmf_err("BRCMF_C_UP error %d\n", err); | 3844 | brcmf_err("BRCMF_C_UP error %d\n", err); |
| 3844 | goto exit; | 3845 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0); |
| 3845 | } | 3846 | if (err < 0) |
| 3847 | brcmf_err("setting AP mode failed %d\n", err); | ||
| 3848 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0); | ||
| 3849 | if (err < 0) | ||
| 3850 | brcmf_err("setting INFRA mode failed %d\n", err); | ||
| 3846 | } else { | 3851 | } else { |
| 3847 | bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx); | 3852 | bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx); |
| 3848 | bss_enable.enable = cpu_to_le32(0); | 3853 | bss_enable.enable = cpu_to_le32(0); |
| @@ -3855,7 +3860,6 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) | |||
| 3855 | set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); | 3860 | set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); |
| 3856 | clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); | 3861 | clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); |
| 3857 | 3862 | ||
| 3858 | exit: | ||
| 3859 | return err; | 3863 | return err; |
| 3860 | } | 3864 | } |
| 3861 | 3865 | ||
| @@ -4124,10 +4128,6 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = { | |||
| 4124 | }, | 4128 | }, |
| 4125 | { | 4129 | { |
| 4126 | .max = 1, | 4130 | .max = 1, |
| 4127 | .types = BIT(NL80211_IFTYPE_P2P_DEVICE) | ||
| 4128 | }, | ||
| 4129 | { | ||
| 4130 | .max = 1, | ||
| 4131 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | | 4131 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | |
| 4132 | BIT(NL80211_IFTYPE_P2P_GO) | 4132 | BIT(NL80211_IFTYPE_P2P_GO) |
| 4133 | }, | 4133 | }, |
| @@ -4183,8 +4183,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) | |||
| 4183 | BIT(NL80211_IFTYPE_ADHOC) | | 4183 | BIT(NL80211_IFTYPE_ADHOC) | |
| 4184 | BIT(NL80211_IFTYPE_AP) | | 4184 | BIT(NL80211_IFTYPE_AP) | |
| 4185 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | 4185 | BIT(NL80211_IFTYPE_P2P_CLIENT) | |
| 4186 | BIT(NL80211_IFTYPE_P2P_GO) | | 4186 | BIT(NL80211_IFTYPE_P2P_GO); |
| 4187 | BIT(NL80211_IFTYPE_P2P_DEVICE); | ||
| 4188 | wiphy->iface_combinations = brcmf_iface_combos; | 4187 | wiphy->iface_combinations = brcmf_iface_combos; |
| 4189 | wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); | 4188 | wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); |
| 4190 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; | 4189 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index c6451c61407a..e2340b231aa1 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
| @@ -274,6 +274,130 @@ static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br) | |||
| 274 | } | 274 | } |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | /** | ||
| 278 | * This function frees the WL per-device resources. | ||
| 279 | * | ||
| 280 | * This function frees resources owned by the WL device pointed to | ||
| 281 | * by the wl parameter. | ||
| 282 | * | ||
| 283 | * precondition: can both be called locked and unlocked | ||
| 284 | * | ||
| 285 | */ | ||
| 286 | static void brcms_free(struct brcms_info *wl) | ||
| 287 | { | ||
| 288 | struct brcms_timer *t, *next; | ||
| 289 | |||
| 290 | /* free ucode data */ | ||
| 291 | if (wl->fw.fw_cnt) | ||
| 292 | brcms_ucode_data_free(&wl->ucode); | ||
| 293 | if (wl->irq) | ||
| 294 | free_irq(wl->irq, wl); | ||
| 295 | |||
| 296 | /* kill dpc */ | ||
| 297 | tasklet_kill(&wl->tasklet); | ||
| 298 | |||
| 299 | if (wl->pub) { | ||
| 300 | brcms_debugfs_detach(wl->pub); | ||
| 301 | brcms_c_module_unregister(wl->pub, "linux", wl); | ||
| 302 | } | ||
| 303 | |||
| 304 | /* free common resources */ | ||
| 305 | if (wl->wlc) { | ||
| 306 | brcms_c_detach(wl->wlc); | ||
| 307 | wl->wlc = NULL; | ||
| 308 | wl->pub = NULL; | ||
| 309 | } | ||
| 310 | |||
| 311 | /* virtual interface deletion is deferred so we cannot spinwait */ | ||
| 312 | |||
| 313 | /* wait for all pending callbacks to complete */ | ||
| 314 | while (atomic_read(&wl->callbacks) > 0) | ||
| 315 | schedule(); | ||
| 316 | |||
| 317 | /* free timers */ | ||
| 318 | for (t = wl->timers; t; t = next) { | ||
| 319 | next = t->next; | ||
| 320 | #ifdef DEBUG | ||
| 321 | kfree(t->name); | ||
| 322 | #endif | ||
| 323 | kfree(t); | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | /* | ||
| 328 | * called from both kernel as from this kernel module (error flow on attach) | ||
| 329 | * precondition: perimeter lock is not acquired. | ||
| 330 | */ | ||
| 331 | static void brcms_remove(struct bcma_device *pdev) | ||
| 332 | { | ||
| 333 | struct ieee80211_hw *hw = bcma_get_drvdata(pdev); | ||
| 334 | struct brcms_info *wl = hw->priv; | ||
| 335 | |||
| 336 | if (wl->wlc) { | ||
| 337 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | ||
| 338 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | ||
| 339 | ieee80211_unregister_hw(hw); | ||
| 340 | } | ||
| 341 | |||
| 342 | brcms_free(wl); | ||
| 343 | |||
| 344 | bcma_set_drvdata(pdev, NULL); | ||
| 345 | ieee80211_free_hw(hw); | ||
| 346 | } | ||
| 347 | |||
| 348 | /* | ||
| 349 | * Precondition: Since this function is called in brcms_pci_probe() context, | ||
| 350 | * no locking is required. | ||
| 351 | */ | ||
| 352 | static void brcms_release_fw(struct brcms_info *wl) | ||
| 353 | { | ||
| 354 | int i; | ||
| 355 | for (i = 0; i < MAX_FW_IMAGES; i++) { | ||
| 356 | release_firmware(wl->fw.fw_bin[i]); | ||
| 357 | release_firmware(wl->fw.fw_hdr[i]); | ||
| 358 | } | ||
| 359 | } | ||
| 360 | |||
| 361 | /* | ||
| 362 | * Precondition: Since this function is called in brcms_pci_probe() context, | ||
| 363 | * no locking is required. | ||
| 364 | */ | ||
| 365 | static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) | ||
| 366 | { | ||
| 367 | int status; | ||
| 368 | struct device *device = &pdev->dev; | ||
| 369 | char fw_name[100]; | ||
| 370 | int i; | ||
| 371 | |||
| 372 | memset(&wl->fw, 0, sizeof(struct brcms_firmware)); | ||
| 373 | for (i = 0; i < MAX_FW_IMAGES; i++) { | ||
| 374 | if (brcms_firmwares[i] == NULL) | ||
| 375 | break; | ||
| 376 | sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], | ||
| 377 | UCODE_LOADER_API_VER); | ||
| 378 | status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); | ||
| 379 | if (status) { | ||
| 380 | wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | ||
| 381 | KBUILD_MODNAME, fw_name); | ||
| 382 | return status; | ||
| 383 | } | ||
| 384 | sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], | ||
| 385 | UCODE_LOADER_API_VER); | ||
| 386 | status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); | ||
| 387 | if (status) { | ||
| 388 | wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | ||
| 389 | KBUILD_MODNAME, fw_name); | ||
| 390 | return status; | ||
| 391 | } | ||
| 392 | wl->fw.hdr_num_entries[i] = | ||
| 393 | wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); | ||
| 394 | } | ||
| 395 | wl->fw.fw_cnt = i; | ||
| 396 | status = brcms_ucode_data_init(wl, &wl->ucode); | ||
| 397 | brcms_release_fw(wl); | ||
| 398 | return status; | ||
| 399 | } | ||
| 400 | |||
| 277 | static void brcms_ops_tx(struct ieee80211_hw *hw, | 401 | static void brcms_ops_tx(struct ieee80211_hw *hw, |
| 278 | struct ieee80211_tx_control *control, | 402 | struct ieee80211_tx_control *control, |
| 279 | struct sk_buff *skb) | 403 | struct sk_buff *skb) |
| @@ -306,6 +430,14 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
| 306 | if (!blocked) | 430 | if (!blocked) |
| 307 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | 431 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
| 308 | 432 | ||
| 433 | if (!wl->ucode.bcm43xx_bomminor) { | ||
| 434 | err = brcms_request_fw(wl, wl->wlc->hw->d11core); | ||
| 435 | if (err) { | ||
| 436 | brcms_remove(wl->wlc->hw->d11core); | ||
| 437 | return -ENOENT; | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 309 | spin_lock_bh(&wl->lock); | 441 | spin_lock_bh(&wl->lock); |
| 310 | /* avoid acknowledging frames before a non-monitor device is added */ | 442 | /* avoid acknowledging frames before a non-monitor device is added */ |
| 311 | wl->mute_tx = true; | 443 | wl->mute_tx = true; |
| @@ -793,128 +925,6 @@ void brcms_dpc(unsigned long data) | |||
| 793 | wake_up(&wl->tx_flush_wq); | 925 | wake_up(&wl->tx_flush_wq); |
| 794 | } | 926 | } |
| 795 | 927 | ||
| 796 | /* | ||
| 797 | * Precondition: Since this function is called in brcms_pci_probe() context, | ||
| 798 | * no locking is required. | ||
| 799 | */ | ||
| 800 | static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) | ||
| 801 | { | ||
| 802 | int status; | ||
| 803 | struct device *device = &pdev->dev; | ||
| 804 | char fw_name[100]; | ||
| 805 | int i; | ||
| 806 | |||
| 807 | memset(&wl->fw, 0, sizeof(struct brcms_firmware)); | ||
| 808 | for (i = 0; i < MAX_FW_IMAGES; i++) { | ||
| 809 | if (brcms_firmwares[i] == NULL) | ||
| 810 | break; | ||
| 811 | sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], | ||
| 812 | UCODE_LOADER_API_VER); | ||
| 813 | status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); | ||
| 814 | if (status) { | ||
| 815 | wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | ||
| 816 | KBUILD_MODNAME, fw_name); | ||
| 817 | return status; | ||
| 818 | } | ||
| 819 | sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], | ||
| 820 | UCODE_LOADER_API_VER); | ||
| 821 | status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); | ||
| 822 | if (status) { | ||
| 823 | wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | ||
| 824 | KBUILD_MODNAME, fw_name); | ||
| 825 | return status; | ||
| 826 | } | ||
| 827 | wl->fw.hdr_num_entries[i] = | ||
| 828 | wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); | ||
| 829 | } | ||
| 830 | wl->fw.fw_cnt = i; | ||
| 831 | return brcms_ucode_data_init(wl, &wl->ucode); | ||
| 832 | } | ||
| 833 | |||
| 834 | /* | ||
| 835 | * Precondition: Since this function is called in brcms_pci_probe() context, | ||
| 836 | * no locking is required. | ||
| 837 | */ | ||
| 838 | static void brcms_release_fw(struct brcms_info *wl) | ||
| 839 | { | ||
| 840 | int i; | ||
| 841 | for (i = 0; i < MAX_FW_IMAGES; i++) { | ||
| 842 | release_firmware(wl->fw.fw_bin[i]); | ||
| 843 | release_firmware(wl->fw.fw_hdr[i]); | ||
| 844 | } | ||
| 845 | } | ||
| 846 | |||
| 847 | /** | ||
| 848 | * This function frees the WL per-device resources. | ||
| 849 | * | ||
| 850 | * This function frees resources owned by the WL device pointed to | ||
| 851 | * by the wl parameter. | ||
| 852 | * | ||
| 853 | * precondition: can both be called locked and unlocked | ||
| 854 | * | ||
| 855 | */ | ||
| 856 | static void brcms_free(struct brcms_info *wl) | ||
| 857 | { | ||
| 858 | struct brcms_timer *t, *next; | ||
| 859 | |||
| 860 | /* free ucode data */ | ||
| 861 | if (wl->fw.fw_cnt) | ||
| 862 | brcms_ucode_data_free(&wl->ucode); | ||
| 863 | if (wl->irq) | ||
| 864 | free_irq(wl->irq, wl); | ||
| 865 | |||
| 866 | /* kill dpc */ | ||
| 867 | tasklet_kill(&wl->tasklet); | ||
| 868 | |||
| 869 | if (wl->pub) { | ||
| 870 | brcms_debugfs_detach(wl->pub); | ||
| 871 | brcms_c_module_unregister(wl->pub, "linux", wl); | ||
| 872 | } | ||
| 873 | |||
| 874 | /* free common resources */ | ||
| 875 | if (wl->wlc) { | ||
| 876 | brcms_c_detach(wl->wlc); | ||
| 877 | wl->wlc = NULL; | ||
| 878 | wl->pub = NULL; | ||
| 879 | } | ||
| 880 | |||
| 881 | /* virtual interface deletion is deferred so we cannot spinwait */ | ||
| 882 | |||
| 883 | /* wait for all pending callbacks to complete */ | ||
| 884 | while (atomic_read(&wl->callbacks) > 0) | ||
| 885 | schedule(); | ||
| 886 | |||
| 887 | /* free timers */ | ||
| 888 | for (t = wl->timers; t; t = next) { | ||
| 889 | next = t->next; | ||
| 890 | #ifdef DEBUG | ||
| 891 | kfree(t->name); | ||
| 892 | #endif | ||
| 893 | kfree(t); | ||
| 894 | } | ||
| 895 | } | ||
| 896 | |||
| 897 | /* | ||
| 898 | * called from both kernel as from this kernel module (error flow on attach) | ||
| 899 | * precondition: perimeter lock is not acquired. | ||
| 900 | */ | ||
| 901 | static void brcms_remove(struct bcma_device *pdev) | ||
| 902 | { | ||
| 903 | struct ieee80211_hw *hw = bcma_get_drvdata(pdev); | ||
| 904 | struct brcms_info *wl = hw->priv; | ||
| 905 | |||
| 906 | if (wl->wlc) { | ||
| 907 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | ||
| 908 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | ||
| 909 | ieee80211_unregister_hw(hw); | ||
| 910 | } | ||
| 911 | |||
| 912 | brcms_free(wl); | ||
| 913 | |||
| 914 | bcma_set_drvdata(pdev, NULL); | ||
| 915 | ieee80211_free_hw(hw); | ||
| 916 | } | ||
| 917 | |||
| 918 | static irqreturn_t brcms_isr(int irq, void *dev_id) | 928 | static irqreturn_t brcms_isr(int irq, void *dev_id) |
| 919 | { | 929 | { |
| 920 | struct brcms_info *wl; | 930 | struct brcms_info *wl; |
| @@ -1047,18 +1057,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) | |||
| 1047 | spin_lock_init(&wl->lock); | 1057 | spin_lock_init(&wl->lock); |
| 1048 | spin_lock_init(&wl->isr_lock); | 1058 | spin_lock_init(&wl->isr_lock); |
| 1049 | 1059 | ||
| 1050 | /* prepare ucode */ | ||
| 1051 | if (brcms_request_fw(wl, pdev) < 0) { | ||
| 1052 | wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " | ||
| 1053 | "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); | ||
| 1054 | brcms_release_fw(wl); | ||
| 1055 | brcms_remove(pdev); | ||
| 1056 | return NULL; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | /* common load-time initialization */ | 1060 | /* common load-time initialization */ |
| 1060 | wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); | 1061 | wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); |
| 1061 | brcms_release_fw(wl); | ||
| 1062 | if (!wl->wlc) { | 1062 | if (!wl->wlc) { |
| 1063 | wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", | 1063 | wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", |
| 1064 | KBUILD_MODNAME, err); | 1064 | KBUILD_MODNAME, err); |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index d215b4d3c51b..e7f6deaf715e 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
| @@ -1393,8 +1393,10 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
| 1393 | queue_work(adapter->workqueue, &adapter->main_work); | 1393 | queue_work(adapter->workqueue, &adapter->main_work); |
| 1394 | 1394 | ||
| 1395 | /* Perform internal scan synchronously */ | 1395 | /* Perform internal scan synchronously */ |
| 1396 | if (!priv->scan_request) | 1396 | if (!priv->scan_request) { |
| 1397 | dev_dbg(adapter->dev, "wait internal scan\n"); | ||
| 1397 | mwifiex_wait_queue_complete(adapter, cmd_node); | 1398 | mwifiex_wait_queue_complete(adapter, cmd_node); |
| 1399 | } | ||
| 1398 | } else { | 1400 | } else { |
| 1399 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 1401 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
| 1400 | flags); | 1402 | flags); |
| @@ -1793,7 +1795,12 @@ check_next_scan: | |||
| 1793 | /* Need to indicate IOCTL complete */ | 1795 | /* Need to indicate IOCTL complete */ |
| 1794 | if (adapter->curr_cmd->wait_q_enabled) { | 1796 | if (adapter->curr_cmd->wait_q_enabled) { |
| 1795 | adapter->cmd_wait_q.status = 0; | 1797 | adapter->cmd_wait_q.status = 0; |
| 1796 | mwifiex_complete_cmd(adapter, adapter->curr_cmd); | 1798 | if (!priv->scan_request) { |
| 1799 | dev_dbg(adapter->dev, | ||
| 1800 | "complete internal scan\n"); | ||
| 1801 | mwifiex_complete_cmd(adapter, | ||
| 1802 | adapter->curr_cmd); | ||
| 1803 | } | ||
| 1797 | } | 1804 | } |
| 1798 | if (priv->report_scan_result) | 1805 | if (priv->report_scan_result) |
| 1799 | priv->report_scan_result = false; | 1806 | priv->report_scan_result = false; |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 2bf4efa33186..76cd47eb901e 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
| @@ -20,6 +20,7 @@ if RT2X00 | |||
| 20 | config RT2400PCI | 20 | config RT2400PCI |
| 21 | tristate "Ralink rt2400 (PCI/PCMCIA) support" | 21 | tristate "Ralink rt2400 (PCI/PCMCIA) support" |
| 22 | depends on PCI | 22 | depends on PCI |
| 23 | select RT2X00_LIB_MMIO | ||
| 23 | select RT2X00_LIB_PCI | 24 | select RT2X00_LIB_PCI |
| 24 | select EEPROM_93CX6 | 25 | select EEPROM_93CX6 |
| 25 | ---help--- | 26 | ---help--- |
| @@ -31,6 +32,7 @@ config RT2400PCI | |||
| 31 | config RT2500PCI | 32 | config RT2500PCI |
| 32 | tristate "Ralink rt2500 (PCI/PCMCIA) support" | 33 | tristate "Ralink rt2500 (PCI/PCMCIA) support" |
| 33 | depends on PCI | 34 | depends on PCI |
| 35 | select RT2X00_LIB_MMIO | ||
| 34 | select RT2X00_LIB_PCI | 36 | select RT2X00_LIB_PCI |
| 35 | select EEPROM_93CX6 | 37 | select EEPROM_93CX6 |
| 36 | ---help--- | 38 | ---help--- |
| @@ -43,6 +45,7 @@ config RT61PCI | |||
| 43 | tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support" | 45 | tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support" |
| 44 | depends on PCI | 46 | depends on PCI |
| 45 | select RT2X00_LIB_PCI | 47 | select RT2X00_LIB_PCI |
| 48 | select RT2X00_LIB_MMIO | ||
| 46 | select RT2X00_LIB_FIRMWARE | 49 | select RT2X00_LIB_FIRMWARE |
| 47 | select RT2X00_LIB_CRYPTO | 50 | select RT2X00_LIB_CRYPTO |
| 48 | select CRC_ITU_T | 51 | select CRC_ITU_T |
| @@ -57,6 +60,7 @@ config RT2800PCI | |||
| 57 | tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" | 60 | tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" |
| 58 | depends on PCI || SOC_RT288X || SOC_RT305X | 61 | depends on PCI || SOC_RT288X || SOC_RT305X |
| 59 | select RT2800_LIB | 62 | select RT2800_LIB |
| 63 | select RT2X00_LIB_MMIO | ||
| 60 | select RT2X00_LIB_PCI if PCI | 64 | select RT2X00_LIB_PCI if PCI |
| 61 | select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X | 65 | select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X |
| 62 | select RT2X00_LIB_FIRMWARE | 66 | select RT2X00_LIB_FIRMWARE |
| @@ -185,6 +189,9 @@ endif | |||
| 185 | config RT2800_LIB | 189 | config RT2800_LIB |
| 186 | tristate | 190 | tristate |
| 187 | 191 | ||
| 192 | config RT2X00_LIB_MMIO | ||
| 193 | tristate | ||
| 194 | |||
| 188 | config RT2X00_LIB_PCI | 195 | config RT2X00_LIB_PCI |
| 189 | tristate | 196 | tristate |
| 190 | select RT2X00_LIB | 197 | select RT2X00_LIB |
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile index 349d5b8284a4..f069d8bc5b67 100644 --- a/drivers/net/wireless/rt2x00/Makefile +++ b/drivers/net/wireless/rt2x00/Makefile | |||
| @@ -9,6 +9,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o | |||
| 9 | rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o | 9 | rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o |
| 10 | 10 | ||
| 11 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o | 11 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o |
| 12 | obj-$(CONFIG_RT2X00_LIB_MMIO) += rt2x00mmio.o | ||
| 12 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o | 13 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o |
| 13 | obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o | 14 | obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o |
| 14 | obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o | 15 | obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 221beaaa83f1..dcfb54e0c516 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 35 | 35 | ||
| 36 | #include "rt2x00.h" | 36 | #include "rt2x00.h" |
| 37 | #include "rt2x00mmio.h" | ||
| 37 | #include "rt2x00pci.h" | 38 | #include "rt2x00pci.h" |
| 38 | #include "rt2400pci.h" | 39 | #include "rt2400pci.h" |
| 39 | 40 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 39edc59e8d03..e1d2dc9ed28a 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 35 | 35 | ||
| 36 | #include "rt2x00.h" | 36 | #include "rt2x00.h" |
| 37 | #include "rt2x00mmio.h" | ||
| 37 | #include "rt2x00pci.h" | 38 | #include "rt2x00pci.h" |
| 38 | #include "rt2500pci.h" | 39 | #include "rt2500pci.h" |
| 39 | 40 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index ded73da4de0b..ba5a05625aaa 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/eeprom_93cx6.h> | 41 | #include <linux/eeprom_93cx6.h> |
| 42 | 42 | ||
| 43 | #include "rt2x00.h" | 43 | #include "rt2x00.h" |
| 44 | #include "rt2x00mmio.h" | ||
| 44 | #include "rt2x00pci.h" | 45 | #include "rt2x00pci.h" |
| 45 | #include "rt2x00soc.h" | 46 | #include "rt2x00soc.h" |
| 46 | #include "rt2800lib.h" | 47 | #include "rt2800lib.h" |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.c b/drivers/net/wireless/rt2x00/rt2x00mmio.c new file mode 100644 index 000000000000..d84a680ba0c9 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00mmio.c | |||
| @@ -0,0 +1,216 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00mmio | ||
| 23 | Abstract: rt2x00 generic mmio device routines. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/dma-mapping.h> | ||
| 27 | #include <linux/kernel.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/slab.h> | ||
| 30 | |||
| 31 | #include "rt2x00.h" | ||
| 32 | #include "rt2x00mmio.h" | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Register access. | ||
| 36 | */ | ||
| 37 | int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | ||
| 38 | const unsigned int offset, | ||
| 39 | const struct rt2x00_field32 field, | ||
| 40 | u32 *reg) | ||
| 41 | { | ||
| 42 | unsigned int i; | ||
| 43 | |||
| 44 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | ||
| 45 | return 0; | ||
| 46 | |||
| 47 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 48 | rt2x00pci_register_read(rt2x00dev, offset, reg); | ||
| 49 | if (!rt2x00_get_field32(*reg, field)) | ||
| 50 | return 1; | ||
| 51 | udelay(REGISTER_BUSY_DELAY); | ||
| 52 | } | ||
| 53 | |||
| 54 | printk_once(KERN_ERR "%s() Indirect register access failed: " | ||
| 55 | "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg); | ||
| 56 | *reg = ~0; | ||
| 57 | |||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); | ||
| 61 | |||
| 62 | bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | ||
| 63 | { | ||
| 64 | struct data_queue *queue = rt2x00dev->rx; | ||
| 65 | struct queue_entry *entry; | ||
| 66 | struct queue_entry_priv_pci *entry_priv; | ||
| 67 | struct skb_frame_desc *skbdesc; | ||
| 68 | int max_rx = 16; | ||
| 69 | |||
| 70 | while (--max_rx) { | ||
| 71 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
| 72 | entry_priv = entry->priv_data; | ||
| 73 | |||
| 74 | if (rt2x00dev->ops->lib->get_entry_state(entry)) | ||
| 75 | break; | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Fill in desc fields of the skb descriptor | ||
| 79 | */ | ||
| 80 | skbdesc = get_skb_frame_desc(entry->skb); | ||
| 81 | skbdesc->desc = entry_priv->desc; | ||
| 82 | skbdesc->desc_len = entry->queue->desc_size; | ||
| 83 | |||
| 84 | /* | ||
| 85 | * DMA is already done, notify rt2x00lib that | ||
| 86 | * it finished successfully. | ||
| 87 | */ | ||
| 88 | rt2x00lib_dmastart(entry); | ||
| 89 | rt2x00lib_dmadone(entry); | ||
| 90 | |||
| 91 | /* | ||
| 92 | * Send the frame to rt2x00lib for further processing. | ||
| 93 | */ | ||
| 94 | rt2x00lib_rxdone(entry, GFP_ATOMIC); | ||
| 95 | } | ||
| 96 | |||
| 97 | return !max_rx; | ||
| 98 | } | ||
| 99 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | ||
| 100 | |||
| 101 | void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) | ||
| 102 | { | ||
| 103 | unsigned int i; | ||
| 104 | |||
| 105 | for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) | ||
| 106 | msleep(10); | ||
| 107 | } | ||
| 108 | EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Device initialization handlers. | ||
| 112 | */ | ||
| 113 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | ||
| 114 | struct data_queue *queue) | ||
| 115 | { | ||
| 116 | struct queue_entry_priv_pci *entry_priv; | ||
| 117 | void *addr; | ||
| 118 | dma_addr_t dma; | ||
| 119 | unsigned int i; | ||
| 120 | |||
| 121 | /* | ||
| 122 | * Allocate DMA memory for descriptor and buffer. | ||
| 123 | */ | ||
| 124 | addr = dma_alloc_coherent(rt2x00dev->dev, | ||
| 125 | queue->limit * queue->desc_size, | ||
| 126 | &dma, GFP_KERNEL); | ||
| 127 | if (!addr) | ||
| 128 | return -ENOMEM; | ||
| 129 | |||
| 130 | memset(addr, 0, queue->limit * queue->desc_size); | ||
| 131 | |||
| 132 | /* | ||
| 133 | * Initialize all queue entries to contain valid addresses. | ||
| 134 | */ | ||
| 135 | for (i = 0; i < queue->limit; i++) { | ||
| 136 | entry_priv = queue->entries[i].priv_data; | ||
| 137 | entry_priv->desc = addr + i * queue->desc_size; | ||
| 138 | entry_priv->desc_dma = dma + i * queue->desc_size; | ||
| 139 | } | ||
| 140 | |||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | |||
| 144 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, | ||
| 145 | struct data_queue *queue) | ||
| 146 | { | ||
| 147 | struct queue_entry_priv_pci *entry_priv = | ||
| 148 | queue->entries[0].priv_data; | ||
| 149 | |||
| 150 | if (entry_priv->desc) | ||
| 151 | dma_free_coherent(rt2x00dev->dev, | ||
| 152 | queue->limit * queue->desc_size, | ||
| 153 | entry_priv->desc, entry_priv->desc_dma); | ||
| 154 | entry_priv->desc = NULL; | ||
| 155 | } | ||
| 156 | |||
| 157 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | ||
| 158 | { | ||
| 159 | struct data_queue *queue; | ||
| 160 | int status; | ||
| 161 | |||
| 162 | /* | ||
| 163 | * Allocate DMA | ||
| 164 | */ | ||
| 165 | queue_for_each(rt2x00dev, queue) { | ||
| 166 | status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); | ||
| 167 | if (status) | ||
| 168 | goto exit; | ||
| 169 | } | ||
| 170 | |||
| 171 | /* | ||
| 172 | * Register interrupt handler. | ||
| 173 | */ | ||
| 174 | status = request_irq(rt2x00dev->irq, | ||
| 175 | rt2x00dev->ops->lib->irq_handler, | ||
| 176 | IRQF_SHARED, rt2x00dev->name, rt2x00dev); | ||
| 177 | if (status) { | ||
| 178 | ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", | ||
| 179 | rt2x00dev->irq, status); | ||
| 180 | goto exit; | ||
| 181 | } | ||
| 182 | |||
| 183 | return 0; | ||
| 184 | |||
| 185 | exit: | ||
| 186 | queue_for_each(rt2x00dev, queue) | ||
| 187 | rt2x00pci_free_queue_dma(rt2x00dev, queue); | ||
| 188 | |||
| 189 | return status; | ||
| 190 | } | ||
| 191 | EXPORT_SYMBOL_GPL(rt2x00pci_initialize); | ||
| 192 | |||
| 193 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | ||
| 194 | { | ||
| 195 | struct data_queue *queue; | ||
| 196 | |||
| 197 | /* | ||
| 198 | * Free irq line. | ||
| 199 | */ | ||
| 200 | free_irq(rt2x00dev->irq, rt2x00dev); | ||
| 201 | |||
| 202 | /* | ||
| 203 | * Free DMA | ||
| 204 | */ | ||
| 205 | queue_for_each(rt2x00dev, queue) | ||
| 206 | rt2x00pci_free_queue_dma(rt2x00dev, queue); | ||
| 207 | } | ||
| 208 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); | ||
| 209 | |||
| 210 | /* | ||
| 211 | * rt2x00mmio module information. | ||
| 212 | */ | ||
| 213 | MODULE_AUTHOR(DRV_PROJECT); | ||
| 214 | MODULE_VERSION(DRV_VERSION); | ||
| 215 | MODULE_DESCRIPTION("rt2x00 mmio library"); | ||
| 216 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.h b/drivers/net/wireless/rt2x00/rt2x00mmio.h new file mode 100644 index 000000000000..4ecaf60175bf --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00mmio.h | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00mmio | ||
| 23 | Abstract: Data structures for the rt2x00mmio module. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef RT2X00MMIO_H | ||
| 27 | #define RT2X00MMIO_H | ||
| 28 | |||
| 29 | #include <linux/io.h> | ||
| 30 | |||
| 31 | /* | ||
| 32 | * Register access. | ||
| 33 | */ | ||
| 34 | static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, | ||
| 35 | const unsigned int offset, | ||
| 36 | u32 *value) | ||
| 37 | { | ||
| 38 | *value = readl(rt2x00dev->csr.base + offset); | ||
| 39 | } | ||
| 40 | |||
| 41 | static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, | ||
| 42 | const unsigned int offset, | ||
| 43 | void *value, const u32 length) | ||
| 44 | { | ||
| 45 | memcpy_fromio(value, rt2x00dev->csr.base + offset, length); | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, | ||
| 49 | const unsigned int offset, | ||
| 50 | u32 value) | ||
| 51 | { | ||
| 52 | writel(value, rt2x00dev->csr.base + offset); | ||
| 53 | } | ||
| 54 | |||
| 55 | static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | ||
| 56 | const unsigned int offset, | ||
| 57 | const void *value, | ||
| 58 | const u32 length) | ||
| 59 | { | ||
| 60 | __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * rt2x00pci_regbusy_read - Read from register with busy check | ||
| 65 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
| 66 | * @offset: Register offset | ||
| 67 | * @field: Field to check if register is busy | ||
| 68 | * @reg: Pointer to where register contents should be stored | ||
| 69 | * | ||
| 70 | * This function will read the given register, and checks if the | ||
| 71 | * register is busy. If it is, it will sleep for a couple of | ||
| 72 | * microseconds before reading the register again. If the register | ||
| 73 | * is not read after a certain timeout, this function will return | ||
| 74 | * FALSE. | ||
| 75 | */ | ||
| 76 | int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | ||
| 77 | const unsigned int offset, | ||
| 78 | const struct rt2x00_field32 field, | ||
| 79 | u32 *reg); | ||
| 80 | |||
| 81 | /** | ||
| 82 | * struct queue_entry_priv_pci: Per entry PCI specific information | ||
| 83 | * | ||
| 84 | * @desc: Pointer to device descriptor | ||
| 85 | * @desc_dma: DMA pointer to &desc. | ||
| 86 | * @data: Pointer to device's entry memory. | ||
| 87 | * @data_dma: DMA pointer to &data. | ||
| 88 | */ | ||
| 89 | struct queue_entry_priv_pci { | ||
| 90 | __le32 *desc; | ||
| 91 | dma_addr_t desc_dma; | ||
| 92 | }; | ||
| 93 | |||
| 94 | /** | ||
| 95 | * rt2x00pci_rxdone - Handle RX done events | ||
| 96 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
| 97 | * | ||
| 98 | * Returns true if there are still rx frames pending and false if all | ||
| 99 | * pending rx frames were processed. | ||
| 100 | */ | ||
| 101 | bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); | ||
| 102 | |||
| 103 | /** | ||
| 104 | * rt2x00pci_flush_queue - Flush data queue | ||
| 105 | * @queue: Data queue to stop | ||
| 106 | * @drop: True to drop all pending frames. | ||
| 107 | * | ||
| 108 | * This will wait for a maximum of 100ms, waiting for the queues | ||
| 109 | * to become empty. | ||
| 110 | */ | ||
| 111 | void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); | ||
| 112 | |||
| 113 | /* | ||
| 114 | * Device initialization handlers. | ||
| 115 | */ | ||
| 116 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev); | ||
| 117 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); | ||
| 118 | |||
| 119 | #endif /* RT2X00MMIO_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index a0c8caef3b0a..e87865e33113 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
| @@ -33,182 +33,6 @@ | |||
| 33 | #include "rt2x00pci.h" | 33 | #include "rt2x00pci.h" |
| 34 | 34 | ||
| 35 | /* | 35 | /* |
| 36 | * Register access. | ||
| 37 | */ | ||
| 38 | int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | ||
| 39 | const unsigned int offset, | ||
| 40 | const struct rt2x00_field32 field, | ||
| 41 | u32 *reg) | ||
| 42 | { | ||
| 43 | unsigned int i; | ||
| 44 | |||
| 45 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | ||
| 46 | return 0; | ||
| 47 | |||
| 48 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 49 | rt2x00pci_register_read(rt2x00dev, offset, reg); | ||
| 50 | if (!rt2x00_get_field32(*reg, field)) | ||
| 51 | return 1; | ||
| 52 | udelay(REGISTER_BUSY_DELAY); | ||
| 53 | } | ||
| 54 | |||
| 55 | ERROR(rt2x00dev, "Indirect register access failed: " | ||
| 56 | "offset=0x%.08x, value=0x%.08x\n", offset, *reg); | ||
| 57 | *reg = ~0; | ||
| 58 | |||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); | ||
| 62 | |||
| 63 | bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | ||
| 64 | { | ||
| 65 | struct data_queue *queue = rt2x00dev->rx; | ||
| 66 | struct queue_entry *entry; | ||
| 67 | struct queue_entry_priv_pci *entry_priv; | ||
| 68 | struct skb_frame_desc *skbdesc; | ||
| 69 | int max_rx = 16; | ||
| 70 | |||
| 71 | while (--max_rx) { | ||
| 72 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
| 73 | entry_priv = entry->priv_data; | ||
| 74 | |||
| 75 | if (rt2x00dev->ops->lib->get_entry_state(entry)) | ||
| 76 | break; | ||
| 77 | |||
| 78 | /* | ||
| 79 | * Fill in desc fields of the skb descriptor | ||
| 80 | */ | ||
| 81 | skbdesc = get_skb_frame_desc(entry->skb); | ||
| 82 | skbdesc->desc = entry_priv->desc; | ||
| 83 | skbdesc->desc_len = entry->queue->desc_size; | ||
| 84 | |||
| 85 | /* | ||
| 86 | * DMA is already done, notify rt2x00lib that | ||
| 87 | * it finished successfully. | ||
| 88 | */ | ||
| 89 | rt2x00lib_dmastart(entry); | ||
| 90 | rt2x00lib_dmadone(entry); | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Send the frame to rt2x00lib for further processing. | ||
| 94 | */ | ||
| 95 | rt2x00lib_rxdone(entry, GFP_ATOMIC); | ||
| 96 | } | ||
| 97 | |||
| 98 | return !max_rx; | ||
| 99 | } | ||
| 100 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | ||
| 101 | |||
| 102 | void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) | ||
| 103 | { | ||
| 104 | unsigned int i; | ||
| 105 | |||
| 106 | for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) | ||
| 107 | msleep(10); | ||
| 108 | } | ||
| 109 | EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); | ||
| 110 | |||
| 111 | /* | ||
| 112 | * Device initialization handlers. | ||
| 113 | */ | ||
| 114 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | ||
| 115 | struct data_queue *queue) | ||
| 116 | { | ||
| 117 | struct queue_entry_priv_pci *entry_priv; | ||
| 118 | void *addr; | ||
| 119 | dma_addr_t dma; | ||
| 120 | unsigned int i; | ||
| 121 | |||
| 122 | /* | ||
| 123 | * Allocate DMA memory for descriptor and buffer. | ||
| 124 | */ | ||
| 125 | addr = dma_alloc_coherent(rt2x00dev->dev, | ||
| 126 | queue->limit * queue->desc_size, | ||
| 127 | &dma, GFP_KERNEL); | ||
| 128 | if (!addr) | ||
| 129 | return -ENOMEM; | ||
| 130 | |||
| 131 | memset(addr, 0, queue->limit * queue->desc_size); | ||
| 132 | |||
| 133 | /* | ||
| 134 | * Initialize all queue entries to contain valid addresses. | ||
| 135 | */ | ||
| 136 | for (i = 0; i < queue->limit; i++) { | ||
| 137 | entry_priv = queue->entries[i].priv_data; | ||
| 138 | entry_priv->desc = addr + i * queue->desc_size; | ||
| 139 | entry_priv->desc_dma = dma + i * queue->desc_size; | ||
| 140 | } | ||
| 141 | |||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, | ||
| 146 | struct data_queue *queue) | ||
| 147 | { | ||
| 148 | struct queue_entry_priv_pci *entry_priv = | ||
| 149 | queue->entries[0].priv_data; | ||
| 150 | |||
| 151 | if (entry_priv->desc) | ||
| 152 | dma_free_coherent(rt2x00dev->dev, | ||
| 153 | queue->limit * queue->desc_size, | ||
| 154 | entry_priv->desc, entry_priv->desc_dma); | ||
| 155 | entry_priv->desc = NULL; | ||
| 156 | } | ||
| 157 | |||
| 158 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | ||
| 159 | { | ||
| 160 | struct data_queue *queue; | ||
| 161 | int status; | ||
| 162 | |||
| 163 | /* | ||
| 164 | * Allocate DMA | ||
| 165 | */ | ||
| 166 | queue_for_each(rt2x00dev, queue) { | ||
| 167 | status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); | ||
| 168 | if (status) | ||
| 169 | goto exit; | ||
| 170 | } | ||
| 171 | |||
| 172 | /* | ||
| 173 | * Register interrupt handler. | ||
| 174 | */ | ||
| 175 | status = request_irq(rt2x00dev->irq, | ||
| 176 | rt2x00dev->ops->lib->irq_handler, | ||
| 177 | IRQF_SHARED, rt2x00dev->name, rt2x00dev); | ||
| 178 | if (status) { | ||
| 179 | ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", | ||
| 180 | rt2x00dev->irq, status); | ||
| 181 | goto exit; | ||
| 182 | } | ||
| 183 | |||
| 184 | return 0; | ||
| 185 | |||
| 186 | exit: | ||
| 187 | queue_for_each(rt2x00dev, queue) | ||
| 188 | rt2x00pci_free_queue_dma(rt2x00dev, queue); | ||
| 189 | |||
| 190 | return status; | ||
| 191 | } | ||
| 192 | EXPORT_SYMBOL_GPL(rt2x00pci_initialize); | ||
| 193 | |||
| 194 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | ||
| 195 | { | ||
| 196 | struct data_queue *queue; | ||
| 197 | |||
| 198 | /* | ||
| 199 | * Free irq line. | ||
| 200 | */ | ||
| 201 | free_irq(rt2x00dev->irq, rt2x00dev); | ||
| 202 | |||
| 203 | /* | ||
| 204 | * Free DMA | ||
| 205 | */ | ||
| 206 | queue_for_each(rt2x00dev, queue) | ||
| 207 | rt2x00pci_free_queue_dma(rt2x00dev, queue); | ||
| 208 | } | ||
| 209 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); | ||
| 210 | |||
| 211 | /* | ||
| 212 | * PCI driver handlers. | 36 | * PCI driver handlers. |
| 213 | */ | 37 | */ |
| 214 | static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) | 38 | static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index e2c99f2b9a14..60d90b20f8b9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
| @@ -36,94 +36,6 @@ | |||
| 36 | #define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops) | 36 | #define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops) |
| 37 | 37 | ||
| 38 | /* | 38 | /* |
| 39 | * Register access. | ||
| 40 | */ | ||
| 41 | static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, | ||
| 42 | const unsigned int offset, | ||
| 43 | u32 *value) | ||
| 44 | { | ||
| 45 | *value = readl(rt2x00dev->csr.base + offset); | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, | ||
| 49 | const unsigned int offset, | ||
| 50 | void *value, const u32 length) | ||
| 51 | { | ||
| 52 | memcpy_fromio(value, rt2x00dev->csr.base + offset, length); | ||
| 53 | } | ||
| 54 | |||
| 55 | static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, | ||
| 56 | const unsigned int offset, | ||
| 57 | u32 value) | ||
| 58 | { | ||
| 59 | writel(value, rt2x00dev->csr.base + offset); | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | ||
| 63 | const unsigned int offset, | ||
| 64 | const void *value, | ||
| 65 | const u32 length) | ||
| 66 | { | ||
| 67 | __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); | ||
| 68 | } | ||
| 69 | |||
| 70 | /** | ||
| 71 | * rt2x00pci_regbusy_read - Read from register with busy check | ||
| 72 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
| 73 | * @offset: Register offset | ||
| 74 | * @field: Field to check if register is busy | ||
| 75 | * @reg: Pointer to where register contents should be stored | ||
| 76 | * | ||
| 77 | * This function will read the given register, and checks if the | ||
| 78 | * register is busy. If it is, it will sleep for a couple of | ||
| 79 | * microseconds before reading the register again. If the register | ||
| 80 | * is not read after a certain timeout, this function will return | ||
| 81 | * FALSE. | ||
| 82 | */ | ||
| 83 | int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | ||
| 84 | const unsigned int offset, | ||
| 85 | const struct rt2x00_field32 field, | ||
| 86 | u32 *reg); | ||
| 87 | |||
| 88 | /** | ||
| 89 | * struct queue_entry_priv_pci: Per entry PCI specific information | ||
| 90 | * | ||
| 91 | * @desc: Pointer to device descriptor | ||
| 92 | * @desc_dma: DMA pointer to &desc. | ||
| 93 | * @data: Pointer to device's entry memory. | ||
| 94 | * @data_dma: DMA pointer to &data. | ||
| 95 | */ | ||
| 96 | struct queue_entry_priv_pci { | ||
| 97 | __le32 *desc; | ||
| 98 | dma_addr_t desc_dma; | ||
| 99 | }; | ||
| 100 | |||
| 101 | /** | ||
| 102 | * rt2x00pci_rxdone - Handle RX done events | ||
| 103 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
| 104 | * | ||
| 105 | * Returns true if there are still rx frames pending and false if all | ||
| 106 | * pending rx frames were processed. | ||
| 107 | */ | ||
| 108 | bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); | ||
| 109 | |||
| 110 | /** | ||
| 111 | * rt2x00pci_flush_queue - Flush data queue | ||
| 112 | * @queue: Data queue to stop | ||
| 113 | * @drop: True to drop all pending frames. | ||
| 114 | * | ||
| 115 | * This will wait for a maximum of 100ms, waiting for the queues | ||
| 116 | * to become empty. | ||
| 117 | */ | ||
| 118 | void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); | ||
| 119 | |||
| 120 | /* | ||
| 121 | * Device initialization handlers. | ||
| 122 | */ | ||
| 123 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev); | ||
| 124 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); | ||
| 125 | |||
| 126 | /* | ||
| 127 | * PCI driver handlers. | 39 | * PCI driver handlers. |
| 128 | */ | 40 | */ |
| 129 | int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops); | 41 | int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops); |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index f95792cfcf89..9e3c8ff53e3f 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/eeprom_93cx6.h> | 35 | #include <linux/eeprom_93cx6.h> |
| 36 | 36 | ||
| 37 | #include "rt2x00.h" | 37 | #include "rt2x00.h" |
| 38 | #include "rt2x00mmio.h" | ||
| 38 | #include "rt2x00pci.h" | 39 | #include "rt2x00pci.h" |
| 39 | #include "rt61pci.h" | 40 | #include "rt61pci.h" |
| 40 | 41 | ||
