diff options
Diffstat (limited to 'drivers/net/wireless')
45 files changed, 363 insertions, 202 deletions
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig index cde58fe96254..82e8088ca9b4 100644 --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config ATH10K | 1 | config ATH10K |
| 2 | tristate "Atheros 802.11ac wireless cards support" | 2 | tristate "Atheros 802.11ac wireless cards support" |
| 3 | depends on MAC80211 | 3 | depends on MAC80211 && HAS_DMA |
| 4 | select ATH_COMMON | 4 | select ATH_COMMON |
| 5 | ---help--- | 5 | ---help--- |
| 6 | This module adds support for wireless adapters based on | 6 | This module adds support for wireless adapters based on |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 81b686c6a376..40825d43322e 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
| @@ -325,7 +325,7 @@ ath5k_prepare_multicast(struct ieee80211_hw *hw, | |||
| 325 | struct netdev_hw_addr *ha; | 325 | struct netdev_hw_addr *ha; |
| 326 | 326 | ||
| 327 | mfilt[0] = 0; | 327 | mfilt[0] = 0; |
| 328 | mfilt[1] = 1; | 328 | mfilt[1] = 0; |
| 329 | 329 | ||
| 330 | netdev_hw_addr_list_for_each(ha, mc_list) { | 330 | netdev_hw_addr_list_for_each(ha, mc_list) { |
| 331 | /* calculate XOR of eight 6-bit values */ | 331 | /* calculate XOR of eight 6-bit values */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index d1acfe98918a..1576d58291d4 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
| @@ -610,7 +610,15 @@ static void ar5008_hw_override_ini(struct ath_hw *ah, | |||
| 610 | REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | 610 | REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); |
| 611 | 611 | ||
| 612 | if (AR_SREV_9280_20_OR_LATER(ah)) { | 612 | if (AR_SREV_9280_20_OR_LATER(ah)) { |
| 613 | val = REG_READ(ah, AR_PCU_MISC_MODE2); | 613 | /* |
| 614 | * For AR9280 and above, there is a new feature that allows | ||
| 615 | * Multicast search based on both MAC Address and Key ID. | ||
| 616 | * By default, this feature is enabled. But since the driver | ||
| 617 | * is not using this feature, we switch it off; otherwise | ||
| 618 | * multicast search based on MAC addr only will fail. | ||
| 619 | */ | ||
| 620 | val = REG_READ(ah, AR_PCU_MISC_MODE2) & | ||
| 621 | (~AR_ADHOC_MCAST_KEYID_ENABLE); | ||
| 614 | 622 | ||
| 615 | if (!AR_SREV_9271(ah)) | 623 | if (!AR_SREV_9271(ah)) |
| 616 | val &= ~AR_PCU_MISC_MODE2_HWWAR1; | 624 | val &= ~AR_PCU_MISC_MODE2_HWWAR1; |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 9e582e14da74..5205a3625e84 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
| @@ -1082,7 +1082,7 @@ static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev) | |||
| 1082 | struct device *dev = &hif_dev->udev->dev; | 1082 | struct device *dev = &hif_dev->udev->dev; |
| 1083 | struct device *parent = dev->parent; | 1083 | struct device *parent = dev->parent; |
| 1084 | 1084 | ||
| 1085 | complete(&hif_dev->fw_done); | 1085 | complete_all(&hif_dev->fw_done); |
| 1086 | 1086 | ||
| 1087 | if (parent) | 1087 | if (parent) |
| 1088 | device_lock(parent); | 1088 | device_lock(parent); |
| @@ -1131,7 +1131,7 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) | |||
| 1131 | 1131 | ||
| 1132 | release_firmware(fw); | 1132 | release_firmware(fw); |
| 1133 | hif_dev->flags |= HIF_USB_READY; | 1133 | hif_dev->flags |= HIF_USB_READY; |
| 1134 | complete(&hif_dev->fw_done); | 1134 | complete_all(&hif_dev->fw_done); |
| 1135 | 1135 | ||
| 1136 | return; | 1136 | return; |
| 1137 | 1137 | ||
| @@ -1295,7 +1295,9 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) | |||
| 1295 | 1295 | ||
| 1296 | usb_set_intfdata(interface, NULL); | 1296 | usb_set_intfdata(interface, NULL); |
| 1297 | 1297 | ||
| 1298 | if (!unplugged && (hif_dev->flags & HIF_USB_START)) | 1298 | /* If firmware was loaded we should drop it |
| 1299 | * go back to first stage bootloader. */ | ||
| 1300 | if (!unplugged && (hif_dev->flags & HIF_USB_READY)) | ||
| 1299 | ath9k_hif_usb_reboot(udev); | 1301 | ath9k_hif_usb_reboot(udev); |
| 1300 | 1302 | ||
| 1301 | kfree(hif_dev); | 1303 | kfree(hif_dev); |
| @@ -1316,7 +1318,10 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface, | |||
| 1316 | if (!(hif_dev->flags & HIF_USB_START)) | 1318 | if (!(hif_dev->flags & HIF_USB_START)) |
| 1317 | ath9k_htc_suspend(hif_dev->htc_handle); | 1319 | ath9k_htc_suspend(hif_dev->htc_handle); |
| 1318 | 1320 | ||
| 1319 | ath9k_hif_usb_dealloc_urbs(hif_dev); | 1321 | wait_for_completion(&hif_dev->fw_done); |
| 1322 | |||
| 1323 | if (hif_dev->flags & HIF_USB_READY) | ||
| 1324 | ath9k_hif_usb_dealloc_urbs(hif_dev); | ||
| 1320 | 1325 | ||
| 1321 | return 0; | 1326 | return 0; |
| 1322 | } | 1327 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 71a183ffc77f..c3676bf1d6c4 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
| @@ -861,6 +861,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
| 861 | if (error != 0) | 861 | if (error != 0) |
| 862 | goto err_rx; | 862 | goto err_rx; |
| 863 | 863 | ||
| 864 | ath9k_hw_disable(priv->ah); | ||
| 864 | #ifdef CONFIG_MAC80211_LEDS | 865 | #ifdef CONFIG_MAC80211_LEDS |
| 865 | /* must be initialized before ieee80211_register_hw */ | 866 | /* must be initialized before ieee80211_register_hw */ |
| 866 | priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw, | 867 | priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw, |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index c59ae43b9b35..927992732620 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -146,6 +146,28 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta, | |||
| 146 | ARRAY_SIZE(bf->rates)); | 146 | ARRAY_SIZE(bf->rates)); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, | ||
| 150 | struct sk_buff *skb) | ||
| 151 | { | ||
| 152 | int q; | ||
| 153 | |||
| 154 | q = skb_get_queue_mapping(skb); | ||
| 155 | if (txq == sc->tx.uapsdq) | ||
| 156 | txq = sc->tx.txq_map[q]; | ||
| 157 | |||
| 158 | if (txq != sc->tx.txq_map[q]) | ||
| 159 | return; | ||
| 160 | |||
| 161 | if (WARN_ON(--txq->pending_frames < 0)) | ||
| 162 | txq->pending_frames = 0; | ||
| 163 | |||
| 164 | if (txq->stopped && | ||
| 165 | txq->pending_frames < sc->tx.txq_max_pending[q]) { | ||
| 166 | ieee80211_wake_queue(sc->hw, q); | ||
| 167 | txq->stopped = false; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 149 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 171 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
| 150 | { | 172 | { |
| 151 | struct ath_txq *txq = tid->ac->txq; | 173 | struct ath_txq *txq = tid->ac->txq; |
| @@ -167,6 +189,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
| 167 | if (!bf) { | 189 | if (!bf) { |
| 168 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 190 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); |
| 169 | if (!bf) { | 191 | if (!bf) { |
| 192 | ath_txq_skb_done(sc, txq, skb); | ||
| 170 | ieee80211_free_txskb(sc->hw, skb); | 193 | ieee80211_free_txskb(sc->hw, skb); |
| 171 | continue; | 194 | continue; |
| 172 | } | 195 | } |
| @@ -811,6 +834,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, | |||
| 811 | 834 | ||
| 812 | if (!bf) { | 835 | if (!bf) { |
| 813 | __skb_unlink(skb, &tid->buf_q); | 836 | __skb_unlink(skb, &tid->buf_q); |
| 837 | ath_txq_skb_done(sc, txq, skb); | ||
| 814 | ieee80211_free_txskb(sc->hw, skb); | 838 | ieee80211_free_txskb(sc->hw, skb); |
| 815 | continue; | 839 | continue; |
| 816 | } | 840 | } |
| @@ -1824,6 +1848,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_txq *txq, | |||
| 1824 | 1848 | ||
| 1825 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 1849 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); |
| 1826 | if (!bf) { | 1850 | if (!bf) { |
| 1851 | ath_txq_skb_done(sc, txq, skb); | ||
| 1827 | ieee80211_free_txskb(sc->hw, skb); | 1852 | ieee80211_free_txskb(sc->hw, skb); |
| 1828 | return; | 1853 | return; |
| 1829 | } | 1854 | } |
| @@ -2090,6 +2115,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 2090 | 2115 | ||
| 2091 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 2116 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); |
| 2092 | if (!bf) { | 2117 | if (!bf) { |
| 2118 | ath_txq_skb_done(sc, txq, skb); | ||
| 2093 | if (txctl->paprd) | 2119 | if (txctl->paprd) |
| 2094 | dev_kfree_skb_any(skb); | 2120 | dev_kfree_skb_any(skb); |
| 2095 | else | 2121 | else |
| @@ -2189,7 +2215,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
| 2189 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 2215 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
| 2190 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2216 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
| 2191 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; | 2217 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; |
| 2192 | int q, padpos, padsize; | 2218 | int padpos, padsize; |
| 2193 | unsigned long flags; | 2219 | unsigned long flags; |
| 2194 | 2220 | ||
| 2195 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); | 2221 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); |
| @@ -2225,21 +2251,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
| 2225 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 2251 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
| 2226 | 2252 | ||
| 2227 | __skb_queue_tail(&txq->complete_q, skb); | 2253 | __skb_queue_tail(&txq->complete_q, skb); |
| 2228 | 2254 | ath_txq_skb_done(sc, txq, skb); | |
| 2229 | q = skb_get_queue_mapping(skb); | ||
| 2230 | if (txq == sc->tx.uapsdq) | ||
| 2231 | txq = sc->tx.txq_map[q]; | ||
| 2232 | |||
| 2233 | if (txq == sc->tx.txq_map[q]) { | ||
| 2234 | if (WARN_ON(--txq->pending_frames < 0)) | ||
| 2235 | txq->pending_frames = 0; | ||
| 2236 | |||
| 2237 | if (txq->stopped && | ||
| 2238 | txq->pending_frames < sc->tx.txq_max_pending[q]) { | ||
| 2239 | ieee80211_wake_queue(sc->hw, q); | ||
| 2240 | txq->stopped = false; | ||
| 2241 | } | ||
| 2242 | } | ||
| 2243 | } | 2255 | } |
| 2244 | 2256 | ||
| 2245 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 2257 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index e8308ec30970..ab636767fbde 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c | |||
| @@ -145,7 +145,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, | |||
| 145 | le16_to_cpu(hdr.type), hdr.flags); | 145 | le16_to_cpu(hdr.type), hdr.flags); |
| 146 | if (len <= MAX_MBOXITEM_SIZE) { | 146 | if (len <= MAX_MBOXITEM_SIZE) { |
| 147 | int n = 0; | 147 | int n = 0; |
| 148 | unsigned char printbuf[16 * 3 + 2]; | 148 | char printbuf[16 * 3 + 2]; |
| 149 | unsigned char databuf[MAX_MBOXITEM_SIZE]; | 149 | unsigned char databuf[MAX_MBOXITEM_SIZE]; |
| 150 | void __iomem *src = wmi_buffer(wil, d.addr) + | 150 | void __iomem *src = wmi_buffer(wil, d.addr) + |
| 151 | sizeof(struct wil6210_mbox_hdr); | 151 | sizeof(struct wil6210_mbox_hdr); |
| @@ -416,7 +416,7 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data) | |||
| 416 | seq_printf(s, " SKB = %p\n", skb); | 416 | seq_printf(s, " SKB = %p\n", skb); |
| 417 | 417 | ||
| 418 | if (skb) { | 418 | if (skb) { |
| 419 | unsigned char printbuf[16 * 3 + 2]; | 419 | char printbuf[16 * 3 + 2]; |
| 420 | int i = 0; | 420 | int i = 0; |
| 421 | int len = le16_to_cpu(d->dma.length); | 421 | int len = le16_to_cpu(d->dma.length); |
| 422 | void *p = skb->data; | 422 | void *p = skb->data; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 8e8975562ec3..80099016d21f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
| @@ -242,7 +242,7 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp, | |||
| 242 | { | 242 | { |
| 243 | unsigned long flags; | 243 | unsigned long flags; |
| 244 | 244 | ||
| 245 | if (!ifp) | 245 | if (!ifp || !ifp->ndev) |
| 246 | return; | 246 | return; |
| 247 | 247 | ||
| 248 | brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n", | 248 | brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n", |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index f0d9f7f6c83d..29b1f24c2d0f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | |||
| @@ -1744,13 +1744,14 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) | |||
| 1744 | ulong flags; | 1744 | ulong flags; |
| 1745 | int fifo = BRCMF_FWS_FIFO_BCMC; | 1745 | int fifo = BRCMF_FWS_FIFO_BCMC; |
| 1746 | bool multicast = is_multicast_ether_addr(eh->h_dest); | 1746 | bool multicast = is_multicast_ether_addr(eh->h_dest); |
| 1747 | bool pae = eh->h_proto == htons(ETH_P_PAE); | ||
| 1747 | 1748 | ||
| 1748 | /* determine the priority */ | 1749 | /* determine the priority */ |
| 1749 | if (!skb->priority) | 1750 | if (!skb->priority) |
| 1750 | skb->priority = cfg80211_classify8021d(skb); | 1751 | skb->priority = cfg80211_classify8021d(skb); |
| 1751 | 1752 | ||
| 1752 | drvr->tx_multicast += !!multicast; | 1753 | drvr->tx_multicast += !!multicast; |
| 1753 | if (ntohs(eh->h_proto) == ETH_P_PAE) | 1754 | if (pae) |
| 1754 | atomic_inc(&ifp->pend_8021x_cnt); | 1755 | atomic_inc(&ifp->pend_8021x_cnt); |
| 1755 | 1756 | ||
| 1756 | if (!brcmf_fws_fc_active(fws)) { | 1757 | if (!brcmf_fws_fc_active(fws)) { |
| @@ -1781,6 +1782,11 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) | |||
| 1781 | brcmf_fws_schedule_deq(fws); | 1782 | brcmf_fws_schedule_deq(fws); |
| 1782 | } else { | 1783 | } else { |
| 1783 | brcmf_err("drop skb: no hanger slot\n"); | 1784 | brcmf_err("drop skb: no hanger slot\n"); |
| 1785 | if (pae) { | ||
| 1786 | atomic_dec(&ifp->pend_8021x_cnt); | ||
| 1787 | if (waitqueue_active(&ifp->pend_8021x_wait)) | ||
| 1788 | wake_up(&ifp->pend_8021x_wait); | ||
| 1789 | } | ||
| 1784 | brcmu_pkt_buf_free_skb(skb); | 1790 | brcmu_pkt_buf_free_skb(skb); |
| 1785 | } | 1791 | } |
| 1786 | brcmf_fws_unlock(drvr, flags); | 1792 | brcmf_fws_unlock(drvr, flags); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 277b37ae7126..7fa71f73cfe8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
| @@ -1093,8 +1093,11 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) | |||
| 1093 | brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n "); | 1093 | brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n "); |
| 1094 | err = brcmf_fil_cmd_data_set(vif->ifp, | 1094 | err = brcmf_fil_cmd_data_set(vif->ifp, |
| 1095 | BRCMF_C_DISASSOC, NULL, 0); | 1095 | BRCMF_C_DISASSOC, NULL, 0); |
| 1096 | if (err) | 1096 | if (err) { |
| 1097 | brcmf_err("WLC_DISASSOC failed (%d)\n", err); | 1097 | brcmf_err("WLC_DISASSOC failed (%d)\n", err); |
| 1098 | cfg80211_disconnected(vif->wdev.netdev, 0, | ||
| 1099 | NULL, 0, GFP_KERNEL); | ||
| 1100 | } | ||
| 1098 | clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); | 1101 | clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); |
| 1099 | } | 1102 | } |
| 1100 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); | 1103 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); |
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c index 5862c373d714..e824d4d4a18d 100644 --- a/drivers/net/wireless/cw1200/txrx.c +++ b/drivers/net/wireless/cw1200/txrx.c | |||
| @@ -1165,7 +1165,7 @@ void cw1200_rx_cb(struct cw1200_common *priv, | |||
| 1165 | if (cw1200_handle_action_rx(priv, skb)) | 1165 | if (cw1200_handle_action_rx(priv, skb)) |
| 1166 | return; | 1166 | return; |
| 1167 | } else if (ieee80211_is_beacon(frame->frame_control) && | 1167 | } else if (ieee80211_is_beacon(frame->frame_control) && |
| 1168 | !arg->status && | 1168 | !arg->status && priv->vif && |
| 1169 | !memcmp(ieee80211_get_SA(frame), priv->vif->bss_conf.bssid, | 1169 | !memcmp(ieee80211_get_SA(frame), priv->vif->bss_conf.bssid, |
| 1170 | ETH_ALEN)) { | 1170 | ETH_ALEN)) { |
| 1171 | const u8 *tim_ie; | 1171 | const u8 *tim_ie; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 3952ddf2ddb2..1531a4fc0960 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
| @@ -758,7 +758,7 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
| 758 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 758 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
| 759 | if (ret) | 759 | if (ret) |
| 760 | return ret; | 760 | return ret; |
| 761 | } else { | 761 | } else if (priv->lib->bt_params) { |
| 762 | /* | 762 | /* |
| 763 | * default is 2-wire BT coexexistence support | 763 | * default is 2-wire BT coexexistence support |
| 764 | */ | 764 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index ff8cc75c189d..a70c7b9d9bad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
| @@ -97,6 +97,8 @@ | |||
| 97 | 97 | ||
| 98 | #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) | 98 | #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) |
| 99 | 99 | ||
| 100 | #define APMG_RTC_INT_STT_RFKILL (0x10000000) | ||
| 101 | |||
| 100 | /* Device system time */ | 102 | /* Device system time */ |
| 101 | #define DEVICE_SYSTEM_TIME_REG 0xA0206C | 103 | #define DEVICE_SYSTEM_TIME_REG 0xA0206C |
| 102 | 104 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 7e5e5c2f9f87..83da884cf303 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
| @@ -134,7 +134,7 @@ struct wowlan_key_data { | |||
| 134 | struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc; | 134 | struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc; |
| 135 | struct iwl_wowlan_tkip_params_cmd *tkip; | 135 | struct iwl_wowlan_tkip_params_cmd *tkip; |
| 136 | bool error, use_rsc_tsc, use_tkip; | 136 | bool error, use_rsc_tsc, use_tkip; |
| 137 | int gtk_key_idx; | 137 | int wep_key_idx; |
| 138 | }; | 138 | }; |
| 139 | 139 | ||
| 140 | static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, | 140 | static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, |
| @@ -188,8 +188,8 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, | |||
| 188 | wkc.wep_key.key_offset = 0; | 188 | wkc.wep_key.key_offset = 0; |
| 189 | } else { | 189 | } else { |
| 190 | /* others start at 1 */ | 190 | /* others start at 1 */ |
| 191 | data->gtk_key_idx++; | 191 | data->wep_key_idx++; |
| 192 | wkc.wep_key.key_offset = data->gtk_key_idx; | 192 | wkc.wep_key.key_offset = data->wep_key_idx; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC, | 195 | ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC, |
| @@ -316,8 +316,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, | |||
| 316 | mvm->ptk_ivlen = key->iv_len; | 316 | mvm->ptk_ivlen = key->iv_len; |
| 317 | mvm->ptk_icvlen = key->icv_len; | 317 | mvm->ptk_icvlen = key->icv_len; |
| 318 | } else { | 318 | } else { |
| 319 | data->gtk_key_idx++; | 319 | /* |
| 320 | key->hw_key_idx = data->gtk_key_idx; | 320 | * firmware only supports TSC/RSC for a single key, |
| 321 | * so if there are multiple keep overwriting them | ||
| 322 | * with new ones -- this relies on mac80211 doing | ||
| 323 | * list_add_tail(). | ||
| 324 | */ | ||
| 325 | key->hw_key_idx = 1; | ||
| 321 | mvm->gtk_ivlen = key->iv_len; | 326 | mvm->gtk_ivlen = key->iv_len; |
| 322 | mvm->gtk_icvlen = key->icv_len; | 327 | mvm->gtk_icvlen = key->icv_len; |
| 323 | } | 328 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index e56ed2a84888..c24a744910ac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
| @@ -988,7 +988,11 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 988 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 988 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 989 | char buf[100]; | 989 | char buf[100]; |
| 990 | 990 | ||
| 991 | if (!dbgfs_dir) | 991 | /* |
| 992 | * Check if debugfs directory already exist before creating it. | ||
| 993 | * This may happen when, for example, resetting hw or suspend-resume | ||
| 994 | */ | ||
| 995 | if (!dbgfs_dir || mvmvif->dbgfs_dir) | ||
| 992 | return; | 996 | return; |
| 993 | 997 | ||
| 994 | mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); | 998 | mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index b60d14151721..365095a0c3b3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
| @@ -69,7 +69,6 @@ | |||
| 69 | /* Scan Commands, Responses, Notifications */ | 69 | /* Scan Commands, Responses, Notifications */ |
| 70 | 70 | ||
| 71 | /* Masks for iwl_scan_channel.type flags */ | 71 | /* Masks for iwl_scan_channel.type flags */ |
| 72 | #define SCAN_CHANNEL_TYPE_PASSIVE 0 | ||
| 73 | #define SCAN_CHANNEL_TYPE_ACTIVE BIT(0) | 72 | #define SCAN_CHANNEL_TYPE_ACTIVE BIT(0) |
| 74 | #define SCAN_CHANNEL_NARROW_BAND BIT(22) | 73 | #define SCAN_CHANNEL_NARROW_BAND BIT(22) |
| 75 | 74 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index e08683b20531..f19baf0dea6b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -257,7 +257,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
| 257 | if (ret) | 257 | if (ret) |
| 258 | return ret; | 258 | return ret; |
| 259 | 259 | ||
| 260 | return ieee80211_register_hw(mvm->hw); | 260 | ret = ieee80211_register_hw(mvm->hw); |
| 261 | if (ret) | ||
| 262 | iwl_mvm_leds_exit(mvm); | ||
| 263 | |||
| 264 | return ret; | ||
| 261 | } | 265 | } |
| 262 | 266 | ||
| 263 | static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, | 267 | static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, |
| @@ -385,6 +389,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) | |||
| 385 | ieee80211_wake_queues(mvm->hw); | 389 | ieee80211_wake_queues(mvm->hw); |
| 386 | 390 | ||
| 387 | mvm->vif_count = 0; | 391 | mvm->vif_count = 0; |
| 392 | mvm->rx_ba_sessions = 0; | ||
| 388 | } | 393 | } |
| 389 | 394 | ||
| 390 | static int iwl_mvm_mac_start(struct ieee80211_hw *hw) | 395 | static int iwl_mvm_mac_start(struct ieee80211_hw *hw) |
| @@ -507,6 +512,27 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
| 507 | goto out_unlock; | 512 | goto out_unlock; |
| 508 | 513 | ||
| 509 | /* | 514 | /* |
| 515 | * TODO: remove this temporary code. | ||
| 516 | * Currently MVM FW supports power management only on single MAC. | ||
| 517 | * If new interface added, disable PM on existing interface. | ||
| 518 | * P2P device is a special case, since it is handled by FW similary to | ||
| 519 | * scan. If P2P deviced is added, PM remains enabled on existing | ||
| 520 | * interface. | ||
| 521 | * Note: the method below does not count the new interface being added | ||
| 522 | * at this moment. | ||
| 523 | */ | ||
| 524 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) | ||
| 525 | mvm->vif_count++; | ||
| 526 | if (mvm->vif_count > 1) { | ||
| 527 | IWL_DEBUG_MAC80211(mvm, | ||
| 528 | "Disable power on existing interfaces\n"); | ||
| 529 | ieee80211_iterate_active_interfaces_atomic( | ||
| 530 | mvm->hw, | ||
| 531 | IEEE80211_IFACE_ITER_NORMAL, | ||
| 532 | iwl_mvm_pm_disable_iterator, mvm); | ||
| 533 | } | ||
| 534 | |||
| 535 | /* | ||
| 510 | * The AP binding flow can be done only after the beacon | 536 | * The AP binding flow can be done only after the beacon |
| 511 | * template is configured (which happens only in the mac80211 | 537 | * template is configured (which happens only in the mac80211 |
| 512 | * start_ap() flow), and adding the broadcast station can happen | 538 | * start_ap() flow), and adding the broadcast station can happen |
| @@ -529,27 +555,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
| 529 | goto out_unlock; | 555 | goto out_unlock; |
| 530 | } | 556 | } |
| 531 | 557 | ||
| 532 | /* | ||
| 533 | * TODO: remove this temporary code. | ||
| 534 | * Currently MVM FW supports power management only on single MAC. | ||
| 535 | * If new interface added, disable PM on existing interface. | ||
| 536 | * P2P device is a special case, since it is handled by FW similary to | ||
| 537 | * scan. If P2P deviced is added, PM remains enabled on existing | ||
| 538 | * interface. | ||
| 539 | * Note: the method below does not count the new interface being added | ||
| 540 | * at this moment. | ||
| 541 | */ | ||
| 542 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) | ||
| 543 | mvm->vif_count++; | ||
| 544 | if (mvm->vif_count > 1) { | ||
| 545 | IWL_DEBUG_MAC80211(mvm, | ||
| 546 | "Disable power on existing interfaces\n"); | ||
| 547 | ieee80211_iterate_active_interfaces_atomic( | ||
| 548 | mvm->hw, | ||
| 549 | IEEE80211_IFACE_ITER_NORMAL, | ||
| 550 | iwl_mvm_pm_disable_iterator, mvm); | ||
| 551 | } | ||
| 552 | |||
| 553 | ret = iwl_mvm_mac_ctxt_add(mvm, vif); | 558 | ret = iwl_mvm_mac_ctxt_add(mvm, vif); |
| 554 | if (ret) | 559 | if (ret) |
| 555 | goto out_release; | 560 | goto out_release; |
| @@ -1006,6 +1011,21 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, | |||
| 1006 | mutex_lock(&mvm->mutex); | 1011 | mutex_lock(&mvm->mutex); |
| 1007 | if (old_state == IEEE80211_STA_NOTEXIST && | 1012 | if (old_state == IEEE80211_STA_NOTEXIST && |
| 1008 | new_state == IEEE80211_STA_NONE) { | 1013 | new_state == IEEE80211_STA_NONE) { |
| 1014 | /* | ||
| 1015 | * Firmware bug - it'll crash if the beacon interval is less | ||
| 1016 | * than 16. We can't avoid connecting at all, so refuse the | ||
| 1017 | * station state change, this will cause mac80211 to abandon | ||
| 1018 | * attempts to connect to this AP, and eventually wpa_s will | ||
| 1019 | * blacklist the AP... | ||
| 1020 | */ | ||
| 1021 | if (vif->type == NL80211_IFTYPE_STATION && | ||
| 1022 | vif->bss_conf.beacon_int < 16) { | ||
| 1023 | IWL_ERR(mvm, | ||
| 1024 | "AP %pM beacon interval is %d, refusing due to firmware bug!\n", | ||
| 1025 | sta->addr, vif->bss_conf.beacon_int); | ||
| 1026 | ret = -EINVAL; | ||
| 1027 | goto out_unlock; | ||
| 1028 | } | ||
| 1009 | ret = iwl_mvm_add_sta(mvm, vif, sta); | 1029 | ret = iwl_mvm_add_sta(mvm, vif, sta); |
| 1010 | } else if (old_state == IEEE80211_STA_NONE && | 1030 | } else if (old_state == IEEE80211_STA_NONE && |
| 1011 | new_state == IEEE80211_STA_AUTH) { | 1031 | new_state == IEEE80211_STA_AUTH) { |
| @@ -1038,6 +1058,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, | |||
| 1038 | } else { | 1058 | } else { |
| 1039 | ret = -EIO; | 1059 | ret = -EIO; |
| 1040 | } | 1060 | } |
| 1061 | out_unlock: | ||
| 1041 | mutex_unlock(&mvm->mutex); | 1062 | mutex_unlock(&mvm->mutex); |
| 1042 | 1063 | ||
| 1043 | return ret; | 1064 | return ret; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index d40d7db185d6..420e82d379d9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
| @@ -419,6 +419,7 @@ struct iwl_mvm { | |||
| 419 | struct work_struct sta_drained_wk; | 419 | struct work_struct sta_drained_wk; |
| 420 | unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; | 420 | unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; |
| 421 | atomic_t pending_frames[IWL_MVM_STATION_COUNT]; | 421 | atomic_t pending_frames[IWL_MVM_STATION_COUNT]; |
| 422 | u8 rx_ba_sessions; | ||
| 422 | 423 | ||
| 423 | /* configured by mac80211 */ | 424 | /* configured by mac80211 */ |
| 424 | u32 rts_threshold; | 425 | u32 rts_threshold; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 2157b0f8ced5..acdff6b67e04 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
| @@ -137,8 +137,8 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, | |||
| 137 | { | 137 | { |
| 138 | int fw_idx, req_idx; | 138 | int fw_idx, req_idx; |
| 139 | 139 | ||
| 140 | fw_idx = 0; | 140 | for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0; |
| 141 | for (req_idx = req->n_ssids - 1; req_idx > 0; req_idx--) { | 141 | req_idx--, fw_idx++) { |
| 142 | cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; | 142 | cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; |
| 143 | cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; | 143 | cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; |
| 144 | memcpy(cmd->direct_scan[fw_idx].ssid, | 144 | memcpy(cmd->direct_scan[fw_idx].ssid, |
| @@ -153,7 +153,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, | |||
| 153 | * just to notify that this scan is active and not passive. | 153 | * just to notify that this scan is active and not passive. |
| 154 | * In order to notify the FW of the number of SSIDs we wish to scan (including | 154 | * In order to notify the FW of the number of SSIDs we wish to scan (including |
| 155 | * the zero-length one), we need to set the corresponding bits in chan->type, | 155 | * the zero-length one), we need to set the corresponding bits in chan->type, |
| 156 | * one for each SSID, and set the active bit (first). | 156 | * one for each SSID, and set the active bit (first). The first SSID is already |
| 157 | * included in the probe template, so we need to set only req->n_ssids - 1 bits | ||
| 158 | * in addition to the first bit. | ||
| 157 | */ | 159 | */ |
| 158 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) | 160 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) |
| 159 | { | 161 | { |
| @@ -176,19 +178,12 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, | |||
| 176 | struct iwl_scan_channel *chan = (struct iwl_scan_channel *) | 178 | struct iwl_scan_channel *chan = (struct iwl_scan_channel *) |
| 177 | (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); | 179 | (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); |
| 178 | int i; | 180 | int i; |
| 179 | __le32 chan_type_value; | ||
| 180 | |||
| 181 | if (req->n_ssids > 0) | ||
| 182 | chan_type_value = cpu_to_le32(BIT(req->n_ssids + 1) - 1); | ||
| 183 | else | ||
| 184 | chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE; | ||
| 185 | 181 | ||
| 186 | for (i = 0; i < cmd->channel_count; i++) { | 182 | for (i = 0; i < cmd->channel_count; i++) { |
| 187 | chan->channel = cpu_to_le16(req->channels[i]->hw_value); | 183 | chan->channel = cpu_to_le16(req->channels[i]->hw_value); |
| 184 | chan->type = cpu_to_le32(BIT(req->n_ssids) - 1); | ||
| 188 | if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) | 185 | if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
| 189 | chan->type = SCAN_CHANNEL_TYPE_PASSIVE; | 186 | chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); |
| 190 | else | ||
| 191 | chan->type = chan_type_value; | ||
| 192 | chan->active_dwell = cpu_to_le16(active_dwell); | 187 | chan->active_dwell = cpu_to_le16(active_dwell); |
| 193 | chan->passive_dwell = cpu_to_le16(passive_dwell); | 188 | chan->passive_dwell = cpu_to_le16(passive_dwell); |
| 194 | chan->iteration_count = cpu_to_le16(1); | 189 | chan->iteration_count = cpu_to_le16(1); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 62fe5209093b..563f559b902d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
| @@ -608,6 +608,8 @@ int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta) | |||
| 608 | return ret; | 608 | return ret; |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | #define IWL_MAX_RX_BA_SESSIONS 16 | ||
| 612 | |||
| 611 | int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | 613 | int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, |
| 612 | int tid, u16 ssn, bool start) | 614 | int tid, u16 ssn, bool start) |
| 613 | { | 615 | { |
| @@ -618,11 +620,20 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
| 618 | 620 | ||
| 619 | lockdep_assert_held(&mvm->mutex); | 621 | lockdep_assert_held(&mvm->mutex); |
| 620 | 622 | ||
| 623 | if (start && mvm->rx_ba_sessions >= IWL_MAX_RX_BA_SESSIONS) { | ||
| 624 | IWL_WARN(mvm, "Not enough RX BA SESSIONS\n"); | ||
| 625 | return -ENOSPC; | ||
| 626 | } | ||
| 627 | |||
| 621 | cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); | 628 | cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); |
| 622 | cmd.sta_id = mvm_sta->sta_id; | 629 | cmd.sta_id = mvm_sta->sta_id; |
| 623 | cmd.add_modify = STA_MODE_MODIFY; | 630 | cmd.add_modify = STA_MODE_MODIFY; |
| 624 | cmd.add_immediate_ba_tid = (u8) tid; | 631 | if (start) { |
| 625 | cmd.add_immediate_ba_ssn = cpu_to_le16(ssn); | 632 | cmd.add_immediate_ba_tid = (u8) tid; |
| 633 | cmd.add_immediate_ba_ssn = cpu_to_le16(ssn); | ||
| 634 | } else { | ||
| 635 | cmd.remove_immediate_ba_tid = (u8) tid; | ||
| 636 | } | ||
| 626 | cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID : | 637 | cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID : |
| 627 | STA_MODIFY_REMOVE_BA_TID; | 638 | STA_MODIFY_REMOVE_BA_TID; |
| 628 | 639 | ||
| @@ -648,6 +659,14 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
| 648 | break; | 659 | break; |
| 649 | } | 660 | } |
| 650 | 661 | ||
| 662 | if (!ret) { | ||
| 663 | if (start) | ||
| 664 | mvm->rx_ba_sessions++; | ||
| 665 | else if (mvm->rx_ba_sessions > 0) | ||
| 666 | /* check that restart flow didn't zero the counter */ | ||
| 667 | mvm->rx_ba_sessions--; | ||
| 668 | } | ||
| 669 | |||
| 651 | return ret; | 670 | return ret; |
| 652 | } | 671 | } |
| 653 | 672 | ||
| @@ -896,6 +915,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 896 | struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; | 915 | struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; |
| 897 | struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; | 916 | struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; |
| 898 | u16 txq_id; | 917 | u16 txq_id; |
| 918 | enum iwl_mvm_agg_state old_state; | ||
| 899 | 919 | ||
| 900 | /* | 920 | /* |
| 901 | * First set the agg state to OFF to avoid calling | 921 | * First set the agg state to OFF to avoid calling |
| @@ -905,13 +925,17 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 905 | txq_id = tid_data->txq_id; | 925 | txq_id = tid_data->txq_id; |
| 906 | IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n", | 926 | IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n", |
| 907 | mvmsta->sta_id, tid, txq_id, tid_data->state); | 927 | mvmsta->sta_id, tid, txq_id, tid_data->state); |
| 928 | old_state = tid_data->state; | ||
| 908 | tid_data->state = IWL_AGG_OFF; | 929 | tid_data->state = IWL_AGG_OFF; |
| 909 | spin_unlock_bh(&mvmsta->lock); | 930 | spin_unlock_bh(&mvmsta->lock); |
| 910 | 931 | ||
| 911 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) | 932 | if (old_state >= IWL_AGG_ON) { |
| 912 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); | 933 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) |
| 934 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); | ||
| 935 | |||
| 936 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); | ||
| 937 | } | ||
| 913 | 938 | ||
| 914 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); | ||
| 915 | mvm->queue_to_mac80211[tid_data->txq_id] = | 939 | mvm->queue_to_mac80211[tid_data->txq_id] = |
| 916 | IWL_INVALID_MAC80211_QUEUE; | 940 | IWL_INVALID_MAC80211_QUEUE; |
| 917 | 941 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 81f3ea5b09a4..ff13458efc27 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -130,6 +130,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
| 130 | {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ | 130 | {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ |
| 131 | {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ | 131 | {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ |
| 132 | {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ | 132 | {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ |
| 133 | {IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_abg_cfg)}, /* Half Mini Card */ | ||
| 133 | 134 | ||
| 134 | {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ | 135 | {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ |
| 135 | {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ | 136 | {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index fd848cd1583e..f600e68a410a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
| @@ -888,6 +888,14 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) | |||
| 888 | 888 | ||
| 889 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 889 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
| 890 | if (hw_rfkill) { | 890 | if (hw_rfkill) { |
| 891 | /* | ||
| 892 | * Clear the interrupt in APMG if the NIC is going down. | ||
| 893 | * Note that when the NIC exits RFkill (else branch), we | ||
| 894 | * can't access prph and the NIC will be reset in | ||
| 895 | * start_hw anyway. | ||
| 896 | */ | ||
| 897 | iwl_write_prph(trans, APMG_RTC_INT_STT_REG, | ||
| 898 | APMG_RTC_INT_STT_RFKILL); | ||
| 891 | set_bit(STATUS_RFKILL, &trans_pcie->status); | 899 | set_bit(STATUS_RFKILL, &trans_pcie->status); |
| 892 | if (test_and_clear_bit(STATUS_HCMD_ACTIVE, | 900 | if (test_and_clear_bit(STATUS_HCMD_ACTIVE, |
| 893 | &trans_pcie->status)) | 901 | &trans_pcie->status)) |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 826c15602c46..96cfcdd39079 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
| @@ -670,6 +670,11 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
| 670 | return err; | 670 | return err; |
| 671 | } | 671 | } |
| 672 | 672 | ||
| 673 | /* Reset the entire device */ | ||
| 674 | iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
| 675 | |||
| 676 | usleep_range(10, 15); | ||
| 677 | |||
| 673 | iwl_pcie_apm_init(trans); | 678 | iwl_pcie_apm_init(trans); |
| 674 | 679 | ||
| 675 | /* From now on, the op_mode will be kept updated about RF kill state */ | 680 | /* From now on, the op_mode will be kept updated about RF kill state */ |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ef5fa890a286..89459db4c53b 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
| @@ -1716,9 +1716,9 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
| 1716 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 1716 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
| 1717 | int ret; | 1717 | int ret; |
| 1718 | 1718 | ||
| 1719 | if (priv->bss_mode != NL80211_IFTYPE_STATION) { | 1719 | if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) { |
| 1720 | wiphy_err(wiphy, | 1720 | wiphy_err(wiphy, |
| 1721 | "%s: reject infra assoc request in non-STA mode\n", | 1721 | "%s: reject infra assoc request in non-STA role\n", |
| 1722 | dev->name); | 1722 | dev->name); |
| 1723 | return -EINVAL; | 1723 | return -EINVAL; |
| 1724 | } | 1724 | } |
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 988552dece75..5178c4630d89 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c | |||
| @@ -415,7 +415,8 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates) | |||
| 415 | u32 k = 0; | 415 | u32 k = 0; |
| 416 | struct mwifiex_adapter *adapter = priv->adapter; | 416 | struct mwifiex_adapter *adapter = priv->adapter; |
| 417 | 417 | ||
| 418 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 418 | if (priv->bss_mode == NL80211_IFTYPE_STATION || |
| 419 | priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) { | ||
| 419 | switch (adapter->config_bands) { | 420 | switch (adapter->config_bands) { |
| 420 | case BAND_B: | 421 | case BAND_B: |
| 421 | dev_dbg(adapter->dev, "info: infra band=%d " | 422 | dev_dbg(adapter->dev, "info: infra band=%d " |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index caaf4bd56b30..2cf8b964e966 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
| @@ -693,7 +693,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, | |||
| 693 | if (!ret) { | 693 | if (!ret) { |
| 694 | dev_notice(adapter->dev, | 694 | dev_notice(adapter->dev, |
| 695 | "WLAN FW already running! Skip FW dnld\n"); | 695 | "WLAN FW already running! Skip FW dnld\n"); |
| 696 | goto done; | 696 | return 0; |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | poll_num = MAX_FIRMWARE_POLL_TRIES; | 699 | poll_num = MAX_FIRMWARE_POLL_TRIES; |
| @@ -719,14 +719,8 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, | |||
| 719 | poll_fw: | 719 | poll_fw: |
| 720 | /* Check if the firmware is downloaded successfully or not */ | 720 | /* Check if the firmware is downloaded successfully or not */ |
| 721 | ret = adapter->if_ops.check_fw_status(adapter, poll_num); | 721 | ret = adapter->if_ops.check_fw_status(adapter, poll_num); |
| 722 | if (ret) { | 722 | if (ret) |
| 723 | dev_err(adapter->dev, "FW failed to be active in time\n"); | 723 | dev_err(adapter->dev, "FW failed to be active in time\n"); |
| 724 | return -1; | ||
| 725 | } | ||
| 726 | done: | ||
| 727 | /* re-enable host interrupt for mwifiex after fw dnld is successful */ | ||
| 728 | if (adapter->if_ops.enable_int) | ||
| 729 | adapter->if_ops.enable_int(adapter); | ||
| 730 | 724 | ||
| 731 | return ret; | 725 | return ret; |
| 732 | } | 726 | } |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 1c8a771e8e81..12e778159ec5 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
| @@ -1291,8 +1291,10 @@ int mwifiex_associate(struct mwifiex_private *priv, | |||
| 1291 | { | 1291 | { |
| 1292 | u8 current_bssid[ETH_ALEN]; | 1292 | u8 current_bssid[ETH_ALEN]; |
| 1293 | 1293 | ||
| 1294 | /* Return error if the adapter or table entry is not marked as infra */ | 1294 | /* Return error if the adapter is not STA role or table entry |
| 1295 | if ((priv->bss_mode != NL80211_IFTYPE_STATION) || | 1295 | * is not marked as infra. |
| 1296 | */ | ||
| 1297 | if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) || | ||
| 1296 | (bss_desc->bss_mode != NL80211_IFTYPE_STATION)) | 1298 | (bss_desc->bss_mode != NL80211_IFTYPE_STATION)) |
| 1297 | return -1; | 1299 | return -1; |
| 1298 | 1300 | ||
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index e15ab72fb03d..1753431de361 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
| @@ -427,6 +427,10 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) | |||
| 427 | "Cal data request_firmware() failed\n"); | 427 | "Cal data request_firmware() failed\n"); |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | /* enable host interrupt after fw dnld is successful */ | ||
| 431 | if (adapter->if_ops.enable_int) | ||
| 432 | adapter->if_ops.enable_int(adapter); | ||
| 433 | |||
| 430 | adapter->init_wait_q_woken = false; | 434 | adapter->init_wait_q_woken = false; |
| 431 | ret = mwifiex_init_fw(adapter); | 435 | ret = mwifiex_init_fw(adapter); |
| 432 | if (ret == -1) { | 436 | if (ret == -1) { |
| @@ -478,6 +482,8 @@ err_add_intf: | |||
| 478 | mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev); | 482 | mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev); |
| 479 | rtnl_unlock(); | 483 | rtnl_unlock(); |
| 480 | err_init_fw: | 484 | err_init_fw: |
| 485 | if (adapter->if_ops.disable_int) | ||
| 486 | adapter->if_ops.disable_int(adapter); | ||
| 481 | pr_debug("info: %s: unregister device\n", __func__); | 487 | pr_debug("info: %s: unregister device\n", __func__); |
| 482 | adapter->if_ops.unregister_dev(adapter); | 488 | adapter->if_ops.unregister_dev(adapter); |
| 483 | done: | 489 | done: |
| @@ -855,7 +861,7 @@ mwifiex_add_card(void *card, struct semaphore *sem, | |||
| 855 | INIT_WORK(&adapter->main_work, mwifiex_main_work_queue); | 861 | INIT_WORK(&adapter->main_work, mwifiex_main_work_queue); |
| 856 | 862 | ||
| 857 | /* Register the device. Fill up the private data structure with relevant | 863 | /* Register the device. Fill up the private data structure with relevant |
| 858 | information from the card and request for the required IRQ. */ | 864 | information from the card. */ |
| 859 | if (adapter->if_ops.register_dev(adapter)) { | 865 | if (adapter->if_ops.register_dev(adapter)) { |
| 860 | pr_err("%s: failed to register mwifiex device\n", __func__); | 866 | pr_err("%s: failed to register mwifiex device\n", __func__); |
| 861 | goto err_registerdev; | 867 | goto err_registerdev; |
| @@ -919,6 +925,11 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) | |||
| 919 | if (!adapter) | 925 | if (!adapter) |
| 920 | goto exit_remove; | 926 | goto exit_remove; |
| 921 | 927 | ||
| 928 | /* We can no longer handle interrupts once we start doing the teardown | ||
| 929 | * below. */ | ||
| 930 | if (adapter->if_ops.disable_int) | ||
| 931 | adapter->if_ops.disable_int(adapter); | ||
| 932 | |||
| 922 | adapter->surprise_removed = true; | 933 | adapter->surprise_removed = true; |
| 923 | 934 | ||
| 924 | /* Stop data */ | 935 | /* Stop data */ |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 3da73d36acdf..253e0bd38e25 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
| @@ -601,6 +601,7 @@ struct mwifiex_if_ops { | |||
| 601 | int (*register_dev) (struct mwifiex_adapter *); | 601 | int (*register_dev) (struct mwifiex_adapter *); |
| 602 | void (*unregister_dev) (struct mwifiex_adapter *); | 602 | void (*unregister_dev) (struct mwifiex_adapter *); |
| 603 | int (*enable_int) (struct mwifiex_adapter *); | 603 | int (*enable_int) (struct mwifiex_adapter *); |
| 604 | void (*disable_int) (struct mwifiex_adapter *); | ||
| 604 | int (*process_int_status) (struct mwifiex_adapter *); | 605 | int (*process_int_status) (struct mwifiex_adapter *); |
| 605 | int (*host_to_card) (struct mwifiex_adapter *, u8, struct sk_buff *, | 606 | int (*host_to_card) (struct mwifiex_adapter *, u8, struct sk_buff *, |
| 606 | struct mwifiex_tx_param *); | 607 | struct mwifiex_tx_param *); |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 5ee5ed02eccd..09185c963248 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
| @@ -51,6 +51,7 @@ static struct mwifiex_if_ops sdio_ops; | |||
| 51 | static struct semaphore add_remove_card_sem; | 51 | static struct semaphore add_remove_card_sem; |
| 52 | 52 | ||
| 53 | static int mwifiex_sdio_resume(struct device *dev); | 53 | static int mwifiex_sdio_resume(struct device *dev); |
| 54 | static void mwifiex_sdio_interrupt(struct sdio_func *func); | ||
| 54 | 55 | ||
| 55 | /* | 56 | /* |
| 56 | * SDIO probe. | 57 | * SDIO probe. |
| @@ -296,6 +297,15 @@ static struct sdio_driver mwifiex_sdio = { | |||
| 296 | } | 297 | } |
| 297 | }; | 298 | }; |
| 298 | 299 | ||
| 300 | /* Write data into SDIO card register. Caller claims SDIO device. */ | ||
| 301 | static int | ||
| 302 | mwifiex_write_reg_locked(struct sdio_func *func, u32 reg, u8 data) | ||
| 303 | { | ||
| 304 | int ret = -1; | ||
| 305 | sdio_writeb(func, data, reg, &ret); | ||
| 306 | return ret; | ||
| 307 | } | ||
| 308 | |||
| 299 | /* | 309 | /* |
| 300 | * This function writes data into SDIO card register. | 310 | * This function writes data into SDIO card register. |
| 301 | */ | 311 | */ |
| @@ -303,10 +313,10 @@ static int | |||
| 303 | mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data) | 313 | mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data) |
| 304 | { | 314 | { |
| 305 | struct sdio_mmc_card *card = adapter->card; | 315 | struct sdio_mmc_card *card = adapter->card; |
| 306 | int ret = -1; | 316 | int ret; |
| 307 | 317 | ||
| 308 | sdio_claim_host(card->func); | 318 | sdio_claim_host(card->func); |
| 309 | sdio_writeb(card->func, data, reg, &ret); | 319 | ret = mwifiex_write_reg_locked(card->func, reg, data); |
| 310 | sdio_release_host(card->func); | 320 | sdio_release_host(card->func); |
| 311 | 321 | ||
| 312 | return ret; | 322 | return ret; |
| @@ -685,23 +695,15 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) | |||
| 685 | * The host interrupt mask is read, the disable bit is reset and | 695 | * The host interrupt mask is read, the disable bit is reset and |
| 686 | * written back to the card host interrupt mask register. | 696 | * written back to the card host interrupt mask register. |
| 687 | */ | 697 | */ |
| 688 | static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) | 698 | static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) |
| 689 | { | 699 | { |
| 690 | u8 host_int_mask, host_int_disable = HOST_INT_DISABLE; | 700 | struct sdio_mmc_card *card = adapter->card; |
| 691 | 701 | struct sdio_func *func = card->func; | |
| 692 | /* Read back the host_int_mask register */ | ||
| 693 | if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask)) | ||
| 694 | return -1; | ||
| 695 | |||
| 696 | /* Update with the mask and write back to the register */ | ||
| 697 | host_int_mask &= ~host_int_disable; | ||
| 698 | |||
| 699 | if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) { | ||
| 700 | dev_err(adapter->dev, "disable host interrupt failed\n"); | ||
| 701 | return -1; | ||
| 702 | } | ||
| 703 | 702 | ||
| 704 | return 0; | 703 | sdio_claim_host(func); |
| 704 | mwifiex_write_reg_locked(func, HOST_INT_MASK_REG, 0); | ||
| 705 | sdio_release_irq(func); | ||
| 706 | sdio_release_host(func); | ||
| 705 | } | 707 | } |
| 706 | 708 | ||
| 707 | /* | 709 | /* |
| @@ -713,14 +715,29 @@ static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) | |||
| 713 | static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter) | 715 | static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter) |
| 714 | { | 716 | { |
| 715 | struct sdio_mmc_card *card = adapter->card; | 717 | struct sdio_mmc_card *card = adapter->card; |
| 718 | struct sdio_func *func = card->func; | ||
| 719 | int ret; | ||
| 720 | |||
| 721 | sdio_claim_host(func); | ||
| 722 | |||
| 723 | /* Request the SDIO IRQ */ | ||
| 724 | ret = sdio_claim_irq(func, mwifiex_sdio_interrupt); | ||
| 725 | if (ret) { | ||
| 726 | dev_err(adapter->dev, "claim irq failed: ret=%d\n", ret); | ||
| 727 | goto out; | ||
| 728 | } | ||
| 716 | 729 | ||
| 717 | /* Simply write the mask to the register */ | 730 | /* Simply write the mask to the register */ |
| 718 | if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, | 731 | ret = mwifiex_write_reg_locked(func, HOST_INT_MASK_REG, |
| 719 | card->reg->host_int_enable)) { | 732 | card->reg->host_int_enable); |
| 733 | if (ret) { | ||
| 720 | dev_err(adapter->dev, "enable host interrupt failed\n"); | 734 | dev_err(adapter->dev, "enable host interrupt failed\n"); |
| 721 | return -1; | 735 | sdio_release_irq(func); |
| 722 | } | 736 | } |
| 723 | return 0; | 737 | |
| 738 | out: | ||
| 739 | sdio_release_host(func); | ||
| 740 | return ret; | ||
| 724 | } | 741 | } |
| 725 | 742 | ||
| 726 | /* | 743 | /* |
| @@ -997,9 +1014,6 @@ mwifiex_sdio_interrupt(struct sdio_func *func) | |||
| 997 | } | 1014 | } |
| 998 | adapter = card->adapter; | 1015 | adapter = card->adapter; |
| 999 | 1016 | ||
| 1000 | if (adapter->surprise_removed) | ||
| 1001 | return; | ||
| 1002 | |||
| 1003 | if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP) | 1017 | if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP) |
| 1004 | adapter->ps_state = PS_STATE_AWAKE; | 1018 | adapter->ps_state = PS_STATE_AWAKE; |
| 1005 | 1019 | ||
| @@ -1625,8 +1639,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, | |||
| 1625 | /* Allocate buffer and copy payload */ | 1639 | /* Allocate buffer and copy payload */ |
| 1626 | blk_size = MWIFIEX_SDIO_BLOCK_SIZE; | 1640 | blk_size = MWIFIEX_SDIO_BLOCK_SIZE; |
| 1627 | buf_block_len = (pkt_len + blk_size - 1) / blk_size; | 1641 | buf_block_len = (pkt_len + blk_size - 1) / blk_size; |
| 1628 | *(u16 *) &payload[0] = (u16) pkt_len; | 1642 | *(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len); |
| 1629 | *(u16 *) &payload[2] = type; | 1643 | *(__le16 *)&payload[2] = cpu_to_le16(type); |
| 1630 | 1644 | ||
| 1631 | /* | 1645 | /* |
| 1632 | * This is SDIO specific header | 1646 | * This is SDIO specific header |
| @@ -1728,9 +1742,7 @@ mwifiex_unregister_dev(struct mwifiex_adapter *adapter) | |||
| 1728 | struct sdio_mmc_card *card = adapter->card; | 1742 | struct sdio_mmc_card *card = adapter->card; |
| 1729 | 1743 | ||
| 1730 | if (adapter->card) { | 1744 | if (adapter->card) { |
| 1731 | /* Release the SDIO IRQ */ | ||
| 1732 | sdio_claim_host(card->func); | 1745 | sdio_claim_host(card->func); |
| 1733 | sdio_release_irq(card->func); | ||
| 1734 | sdio_disable_func(card->func); | 1746 | sdio_disable_func(card->func); |
| 1735 | sdio_release_host(card->func); | 1747 | sdio_release_host(card->func); |
| 1736 | sdio_set_drvdata(card->func, NULL); | 1748 | sdio_set_drvdata(card->func, NULL); |
| @@ -1744,7 +1756,7 @@ mwifiex_unregister_dev(struct mwifiex_adapter *adapter) | |||
| 1744 | */ | 1756 | */ |
| 1745 | static int mwifiex_register_dev(struct mwifiex_adapter *adapter) | 1757 | static int mwifiex_register_dev(struct mwifiex_adapter *adapter) |
| 1746 | { | 1758 | { |
| 1747 | int ret = 0; | 1759 | int ret; |
| 1748 | struct sdio_mmc_card *card = adapter->card; | 1760 | struct sdio_mmc_card *card = adapter->card; |
| 1749 | struct sdio_func *func = card->func; | 1761 | struct sdio_func *func = card->func; |
| 1750 | 1762 | ||
| @@ -1753,22 +1765,14 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) | |||
| 1753 | 1765 | ||
| 1754 | sdio_claim_host(func); | 1766 | sdio_claim_host(func); |
| 1755 | 1767 | ||
| 1756 | /* Request the SDIO IRQ */ | ||
| 1757 | ret = sdio_claim_irq(func, mwifiex_sdio_interrupt); | ||
| 1758 | if (ret) { | ||
| 1759 | pr_err("claim irq failed: ret=%d\n", ret); | ||
| 1760 | goto disable_func; | ||
| 1761 | } | ||
| 1762 | |||
| 1763 | /* Set block size */ | 1768 | /* Set block size */ |
| 1764 | ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE); | 1769 | ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE); |
| 1770 | sdio_release_host(func); | ||
| 1765 | if (ret) { | 1771 | if (ret) { |
| 1766 | pr_err("cannot set SDIO block size\n"); | 1772 | pr_err("cannot set SDIO block size\n"); |
| 1767 | ret = -1; | 1773 | return ret; |
| 1768 | goto release_irq; | ||
| 1769 | } | 1774 | } |
| 1770 | 1775 | ||
| 1771 | sdio_release_host(func); | ||
| 1772 | sdio_set_drvdata(func, card); | 1776 | sdio_set_drvdata(func, card); |
| 1773 | 1777 | ||
| 1774 | adapter->dev = &func->dev; | 1778 | adapter->dev = &func->dev; |
| @@ -1776,15 +1780,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) | |||
| 1776 | strcpy(adapter->fw_name, card->firmware); | 1780 | strcpy(adapter->fw_name, card->firmware); |
| 1777 | 1781 | ||
| 1778 | return 0; | 1782 | return 0; |
| 1779 | |||
| 1780 | release_irq: | ||
| 1781 | sdio_release_irq(func); | ||
| 1782 | disable_func: | ||
| 1783 | sdio_disable_func(func); | ||
| 1784 | sdio_release_host(func); | ||
| 1785 | adapter->card = NULL; | ||
| 1786 | |||
| 1787 | return -1; | ||
| 1788 | } | 1783 | } |
| 1789 | 1784 | ||
| 1790 | /* | 1785 | /* |
| @@ -1813,9 +1808,6 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) | |||
| 1813 | */ | 1808 | */ |
| 1814 | mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg); | 1809 | mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg); |
| 1815 | 1810 | ||
| 1816 | /* Disable host interrupt mask register for SDIO */ | ||
| 1817 | mwifiex_sdio_disable_host_int(adapter); | ||
| 1818 | |||
| 1819 | /* Get SDIO ioport */ | 1811 | /* Get SDIO ioport */ |
| 1820 | mwifiex_init_sdio_ioport(adapter); | 1812 | mwifiex_init_sdio_ioport(adapter); |
| 1821 | 1813 | ||
| @@ -1957,6 +1949,7 @@ static struct mwifiex_if_ops sdio_ops = { | |||
| 1957 | .register_dev = mwifiex_register_dev, | 1949 | .register_dev = mwifiex_register_dev, |
| 1958 | .unregister_dev = mwifiex_unregister_dev, | 1950 | .unregister_dev = mwifiex_unregister_dev, |
| 1959 | .enable_int = mwifiex_sdio_enable_host_int, | 1951 | .enable_int = mwifiex_sdio_enable_host_int, |
| 1952 | .disable_int = mwifiex_sdio_disable_host_int, | ||
| 1960 | .process_int_status = mwifiex_process_int_status, | 1953 | .process_int_status = mwifiex_process_int_status, |
| 1961 | .host_to_card = mwifiex_sdio_host_to_card, | 1954 | .host_to_card = mwifiex_sdio_host_to_card, |
| 1962 | .wakeup = mwifiex_pm_wakeup_card, | 1955 | .wakeup = mwifiex_pm_wakeup_card, |
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index 6d51dfdd8251..532ae0ac4dfb 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h | |||
| @@ -92,9 +92,6 @@ | |||
| 92 | /* Host Control Registers : Download host interrupt mask */ | 92 | /* Host Control Registers : Download host interrupt mask */ |
| 93 | #define DN_LD_HOST_INT_MASK (0x2U) | 93 | #define DN_LD_HOST_INT_MASK (0x2U) |
| 94 | 94 | ||
| 95 | /* Disable Host interrupt mask */ | ||
| 96 | #define HOST_INT_DISABLE 0xff | ||
| 97 | |||
| 98 | /* Host Control Registers : Host interrupt status */ | 95 | /* Host Control Registers : Host interrupt status */ |
| 99 | #define HOST_INTSTATUS_REG 0x03 | 96 | #define HOST_INTSTATUS_REG 0x03 |
| 100 | /* Host Control Registers : Upload host interrupt status */ | 97 | /* Host Control Registers : Upload host interrupt status */ |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 206c3e038072..8af97abf7108 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
| @@ -257,10 +257,10 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
| 257 | goto done; | 257 | goto done; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 260 | if (priv->bss_mode == NL80211_IFTYPE_STATION || |
| 261 | priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) { | ||
| 261 | u8 config_bands; | 262 | u8 config_bands; |
| 262 | 263 | ||
| 263 | /* Infra mode */ | ||
| 264 | ret = mwifiex_deauthenticate(priv, NULL); | 264 | ret = mwifiex_deauthenticate(priv, NULL); |
| 265 | if (ret) | 265 | if (ret) |
| 266 | goto done; | 266 | goto done; |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 9b915d3a44be..3e60a31582f8 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | menuconfig RT2X00 | 1 | menuconfig RT2X00 |
| 2 | tristate "Ralink driver support" | 2 | tristate "Ralink driver support" |
| 3 | depends on MAC80211 | 3 | depends on MAC80211 && HAS_DMA |
| 4 | ---help--- | 4 | ---help--- |
| 5 | This will enable the support for the Ralink drivers, | 5 | This will enable the support for the Ralink drivers, |
| 6 | developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. | 6 | developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 6c0a91ff963c..aa95c6cf3545 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
| @@ -936,13 +936,8 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index) | |||
| 936 | spin_unlock_irqrestore(&queue->index_lock, irqflags); | 936 | spin_unlock_irqrestore(&queue->index_lock, irqflags); |
| 937 | } | 937 | } |
| 938 | 938 | ||
| 939 | void rt2x00queue_pause_queue(struct data_queue *queue) | 939 | void rt2x00queue_pause_queue_nocheck(struct data_queue *queue) |
| 940 | { | 940 | { |
| 941 | if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || | ||
| 942 | !test_bit(QUEUE_STARTED, &queue->flags) || | ||
| 943 | test_and_set_bit(QUEUE_PAUSED, &queue->flags)) | ||
| 944 | return; | ||
| 945 | |||
| 946 | switch (queue->qid) { | 941 | switch (queue->qid) { |
| 947 | case QID_AC_VO: | 942 | case QID_AC_VO: |
| 948 | case QID_AC_VI: | 943 | case QID_AC_VI: |
| @@ -958,6 +953,15 @@ void rt2x00queue_pause_queue(struct data_queue *queue) | |||
| 958 | break; | 953 | break; |
| 959 | } | 954 | } |
| 960 | } | 955 | } |
| 956 | void rt2x00queue_pause_queue(struct data_queue *queue) | ||
| 957 | { | ||
| 958 | if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || | ||
| 959 | !test_bit(QUEUE_STARTED, &queue->flags) || | ||
| 960 | test_and_set_bit(QUEUE_PAUSED, &queue->flags)) | ||
| 961 | return; | ||
| 962 | |||
| 963 | rt2x00queue_pause_queue_nocheck(queue); | ||
| 964 | } | ||
| 961 | EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue); | 965 | EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue); |
| 962 | 966 | ||
| 963 | void rt2x00queue_unpause_queue(struct data_queue *queue) | 967 | void rt2x00queue_unpause_queue(struct data_queue *queue) |
| @@ -1019,7 +1023,7 @@ void rt2x00queue_stop_queue(struct data_queue *queue) | |||
| 1019 | return; | 1023 | return; |
| 1020 | } | 1024 | } |
| 1021 | 1025 | ||
| 1022 | rt2x00queue_pause_queue(queue); | 1026 | rt2x00queue_pause_queue_nocheck(queue); |
| 1023 | 1027 | ||
| 1024 | queue->rt2x00dev->ops->lib->stop_queue(queue); | 1028 | queue->rt2x00dev->ops->lib->stop_queue(queue); |
| 1025 | 1029 | ||
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 7253de3d8c66..c2ffce7a907c 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig | |||
| @@ -1,27 +1,20 @@ | |||
| 1 | config RTLWIFI | 1 | menuconfig RTL_CARDS |
| 2 | tristate "Realtek wireless card support" | 2 | tristate "Realtek rtlwifi family of devices" |
| 3 | depends on MAC80211 | 3 | depends on MAC80211 && (PCI || USB) |
| 4 | select FW_LOADER | ||
| 5 | ---help--- | ||
| 6 | This is common code for RTL8192CE/RTL8192CU/RTL8192SE/RTL8723AE | ||
| 7 | drivers. This module does nothing by itself - the various front-end | ||
| 8 | drivers need to be enabled to support any desired devices. | ||
| 9 | |||
| 10 | If you choose to build as a module, it'll be called rtlwifi. | ||
| 11 | |||
| 12 | config RTLWIFI_DEBUG | ||
| 13 | bool "Debugging output for rtlwifi driver family" | ||
| 14 | depends on RTLWIFI | ||
| 15 | default y | 4 | default y |
| 16 | ---help--- | 5 | ---help--- |
| 17 | To use the module option that sets the dynamic-debugging level for, | 6 | This option will enable support for the Realtek mac80211-based |
| 18 | the front-end driver, this parameter must be "Y". For memory-limited | 7 | wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de, |
| 19 | systems, choose "N". If in doubt, choose "Y". | 8 | rtl8723eu, and rtl8188eu share some common code. |
| 9 | |||
| 10 | if RTL_CARDS | ||
| 20 | 11 | ||
| 21 | config RTL8192CE | 12 | config RTL8192CE |
| 22 | tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter" | 13 | tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter" |
| 23 | depends on RTLWIFI && PCI | 14 | depends on PCI |
| 24 | select RTL8192C_COMMON | 15 | select RTL8192C_COMMON |
| 16 | select RTLWIFI | ||
| 17 | select RTLWIFI_PCI | ||
| 25 | ---help--- | 18 | ---help--- |
| 26 | This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe | 19 | This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe |
| 27 | wireless network adapters. | 20 | wireless network adapters. |
| @@ -30,7 +23,9 @@ config RTL8192CE | |||
| 30 | 23 | ||
| 31 | config RTL8192SE | 24 | config RTL8192SE |
| 32 | tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter" | 25 | tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter" |
| 33 | depends on RTLWIFI && PCI | 26 | depends on PCI |
| 27 | select RTLWIFI | ||
| 28 | select RTLWIFI_PCI | ||
| 34 | ---help--- | 29 | ---help--- |
| 35 | This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe | 30 | This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe |
| 36 | wireless network adapters. | 31 | wireless network adapters. |
| @@ -39,7 +34,9 @@ config RTL8192SE | |||
| 39 | 34 | ||
| 40 | config RTL8192DE | 35 | config RTL8192DE |
| 41 | tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter" | 36 | tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter" |
| 42 | depends on RTLWIFI && PCI | 37 | depends on PCI |
| 38 | select RTLWIFI | ||
| 39 | select RTLWIFI_PCI | ||
| 43 | ---help--- | 40 | ---help--- |
| 44 | This is the driver for Realtek RTL8192DE/RTL8188DE 802.11n PCIe | 41 | This is the driver for Realtek RTL8192DE/RTL8188DE 802.11n PCIe |
| 45 | wireless network adapters. | 42 | wireless network adapters. |
| @@ -48,7 +45,9 @@ config RTL8192DE | |||
| 48 | 45 | ||
| 49 | config RTL8723AE | 46 | config RTL8723AE |
| 50 | tristate "Realtek RTL8723AE PCIe Wireless Network Adapter" | 47 | tristate "Realtek RTL8723AE PCIe Wireless Network Adapter" |
| 51 | depends on RTLWIFI && PCI | 48 | depends on PCI |
| 49 | select RTLWIFI | ||
| 50 | select RTLWIFI_PCI | ||
| 52 | ---help--- | 51 | ---help--- |
| 53 | This is the driver for Realtek RTL8723AE 802.11n PCIe | 52 | This is the driver for Realtek RTL8723AE 802.11n PCIe |
| 54 | wireless network adapters. | 53 | wireless network adapters. |
| @@ -57,7 +56,9 @@ config RTL8723AE | |||
| 57 | 56 | ||
| 58 | config RTL8188EE | 57 | config RTL8188EE |
| 59 | tristate "Realtek RTL8188EE Wireless Network Adapter" | 58 | tristate "Realtek RTL8188EE Wireless Network Adapter" |
| 60 | depends on RTLWIFI && PCI | 59 | depends on PCI |
| 60 | select RTLWIFI | ||
| 61 | select RTLWIFI_PCI | ||
| 61 | ---help--- | 62 | ---help--- |
| 62 | This is the driver for Realtek RTL8188EE 802.11n PCIe | 63 | This is the driver for Realtek RTL8188EE 802.11n PCIe |
| 63 | wireless network adapters. | 64 | wireless network adapters. |
| @@ -66,7 +67,9 @@ config RTL8188EE | |||
| 66 | 67 | ||
| 67 | config RTL8192CU | 68 | config RTL8192CU |
| 68 | tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" | 69 | tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" |
| 69 | depends on RTLWIFI && USB | 70 | depends on USB |
| 71 | select RTLWIFI | ||
| 72 | select RTLWIFI_USB | ||
| 70 | select RTL8192C_COMMON | 73 | select RTL8192C_COMMON |
| 71 | ---help--- | 74 | ---help--- |
| 72 | This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB | 75 | This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB |
| @@ -74,7 +77,28 @@ config RTL8192CU | |||
| 74 | 77 | ||
| 75 | If you choose to build it as a module, it will be called rtl8192cu | 78 | If you choose to build it as a module, it will be called rtl8192cu |
| 76 | 79 | ||
| 80 | config RTLWIFI | ||
| 81 | tristate | ||
| 82 | select FW_LOADER | ||
| 83 | |||
| 84 | config RTLWIFI_PCI | ||
| 85 | tristate | ||
| 86 | |||
| 87 | config RTLWIFI_USB | ||
| 88 | tristate | ||
| 89 | |||
| 90 | config RTLWIFI_DEBUG | ||
| 91 | bool "Debugging output for rtlwifi driver family" | ||
| 92 | depends on RTLWIFI | ||
| 93 | default y | ||
| 94 | ---help--- | ||
| 95 | To use the module option that sets the dynamic-debugging level for, | ||
| 96 | the front-end driver, this parameter must be "Y". For memory-limited | ||
| 97 | systems, choose "N". If in doubt, choose "Y". | ||
| 98 | |||
| 77 | config RTL8192C_COMMON | 99 | config RTL8192C_COMMON |
| 78 | tristate | 100 | tristate |
| 79 | depends on RTL8192CE || RTL8192CU | 101 | depends on RTL8192CE || RTL8192CU |
| 80 | default m | 102 | default y |
| 103 | |||
| 104 | endif | ||
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index ff02b874f8d8..d56f023a4b90 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile | |||
| @@ -12,13 +12,11 @@ rtlwifi-objs := \ | |||
| 12 | 12 | ||
| 13 | rtl8192c_common-objs += \ | 13 | rtl8192c_common-objs += \ |
| 14 | 14 | ||
| 15 | ifneq ($(CONFIG_PCI),) | 15 | obj-$(CONFIG_RTLWIFI_PCI) += rtl_pci.o |
| 16 | rtlwifi-objs += pci.o | 16 | rtl_pci-objs := pci.o |
| 17 | endif | ||
| 18 | 17 | ||
| 19 | ifneq ($(CONFIG_USB),) | 18 | obj-$(CONFIG_RTLWIFI_USB) += rtl_usb.o |
| 20 | rtlwifi-objs += usb.o | 19 | rtl_usb-objs := usb.o |
| 21 | endif | ||
| 22 | 20 | ||
| 23 | obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ | 21 | obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ |
| 24 | obj-$(CONFIG_RTL8192CE) += rtl8192ce/ | 22 | obj-$(CONFIG_RTL8192CE) += rtl8192ce/ |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 9d558ac77b0c..7651f5acc14b 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
| @@ -172,6 +172,7 @@ u8 rtl_tid_to_ac(u8 tid) | |||
| 172 | { | 172 | { |
| 173 | return tid_to_ac[tid]; | 173 | return tid_to_ac[tid]; |
| 174 | } | 174 | } |
| 175 | EXPORT_SYMBOL_GPL(rtl_tid_to_ac); | ||
| 175 | 176 | ||
| 176 | static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, | 177 | static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, |
| 177 | struct ieee80211_sta_ht_cap *ht_cap) | 178 | struct ieee80211_sta_ht_cap *ht_cap) |
| @@ -406,6 +407,7 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw) | |||
| 406 | cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); | 407 | cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); |
| 407 | cancel_delayed_work(&rtlpriv->works.fwevt_wq); | 408 | cancel_delayed_work(&rtlpriv->works.fwevt_wq); |
| 408 | } | 409 | } |
| 410 | EXPORT_SYMBOL_GPL(rtl_deinit_deferred_work); | ||
| 409 | 411 | ||
| 410 | void rtl_init_rfkill(struct ieee80211_hw *hw) | 412 | void rtl_init_rfkill(struct ieee80211_hw *hw) |
| 411 | { | 413 | { |
| @@ -439,6 +441,7 @@ void rtl_deinit_rfkill(struct ieee80211_hw *hw) | |||
| 439 | { | 441 | { |
| 440 | wiphy_rfkill_stop_polling(hw->wiphy); | 442 | wiphy_rfkill_stop_polling(hw->wiphy); |
| 441 | } | 443 | } |
| 444 | EXPORT_SYMBOL_GPL(rtl_deinit_rfkill); | ||
| 442 | 445 | ||
| 443 | int rtl_init_core(struct ieee80211_hw *hw) | 446 | int rtl_init_core(struct ieee80211_hw *hw) |
| 444 | { | 447 | { |
| @@ -489,10 +492,12 @@ int rtl_init_core(struct ieee80211_hw *hw) | |||
| 489 | 492 | ||
| 490 | return 0; | 493 | return 0; |
| 491 | } | 494 | } |
| 495 | EXPORT_SYMBOL_GPL(rtl_init_core); | ||
| 492 | 496 | ||
| 493 | void rtl_deinit_core(struct ieee80211_hw *hw) | 497 | void rtl_deinit_core(struct ieee80211_hw *hw) |
| 494 | { | 498 | { |
| 495 | } | 499 | } |
| 500 | EXPORT_SYMBOL_GPL(rtl_deinit_core); | ||
| 496 | 501 | ||
| 497 | void rtl_init_rx_config(struct ieee80211_hw *hw) | 502 | void rtl_init_rx_config(struct ieee80211_hw *hw) |
| 498 | { | 503 | { |
| @@ -501,6 +506,7 @@ void rtl_init_rx_config(struct ieee80211_hw *hw) | |||
| 501 | 506 | ||
| 502 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); | 507 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); |
| 503 | } | 508 | } |
| 509 | EXPORT_SYMBOL_GPL(rtl_init_rx_config); | ||
| 504 | 510 | ||
| 505 | /********************************************************* | 511 | /********************************************************* |
| 506 | * | 512 | * |
| @@ -879,6 +885,7 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 879 | 885 | ||
| 880 | return true; | 886 | return true; |
| 881 | } | 887 | } |
| 888 | EXPORT_SYMBOL_GPL(rtl_tx_mgmt_proc); | ||
| 882 | 889 | ||
| 883 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, | 890 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, |
| 884 | struct ieee80211_tx_info *info, | 891 | struct ieee80211_tx_info *info, |
| @@ -1052,6 +1059,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
| 1052 | 1059 | ||
| 1053 | return true; | 1060 | return true; |
| 1054 | } | 1061 | } |
| 1062 | EXPORT_SYMBOL_GPL(rtl_action_proc); | ||
| 1055 | 1063 | ||
| 1056 | /*should call before software enc*/ | 1064 | /*should call before software enc*/ |
| 1057 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | 1065 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) |
| @@ -1125,6 +1133,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
| 1125 | 1133 | ||
| 1126 | return false; | 1134 | return false; |
| 1127 | } | 1135 | } |
| 1136 | EXPORT_SYMBOL_GPL(rtl_is_special_data); | ||
| 1128 | 1137 | ||
| 1129 | /********************************************************* | 1138 | /********************************************************* |
| 1130 | * | 1139 | * |
| @@ -1300,6 +1309,7 @@ void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 1300 | 1309 | ||
| 1301 | rtlpriv->link_info.bcn_rx_inperiod++; | 1310 | rtlpriv->link_info.bcn_rx_inperiod++; |
| 1302 | } | 1311 | } |
| 1312 | EXPORT_SYMBOL_GPL(rtl_beacon_statistic); | ||
| 1303 | 1313 | ||
| 1304 | void rtl_watchdog_wq_callback(void *data) | 1314 | void rtl_watchdog_wq_callback(void *data) |
| 1305 | { | 1315 | { |
| @@ -1793,6 +1803,7 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) | |||
| 1793 | 1803 | ||
| 1794 | mac->vendor = vendor; | 1804 | mac->vendor = vendor; |
| 1795 | } | 1805 | } |
| 1806 | EXPORT_SYMBOL_GPL(rtl_recognize_peer); | ||
| 1796 | 1807 | ||
| 1797 | /********************************************************* | 1808 | /********************************************************* |
| 1798 | * | 1809 | * |
| @@ -1849,6 +1860,7 @@ struct attribute_group rtl_attribute_group = { | |||
| 1849 | .name = "rtlsysfs", | 1860 | .name = "rtlsysfs", |
| 1850 | .attrs = rtl_sysfs_entries, | 1861 | .attrs = rtl_sysfs_entries, |
| 1851 | }; | 1862 | }; |
| 1863 | EXPORT_SYMBOL_GPL(rtl_attribute_group); | ||
| 1852 | 1864 | ||
| 1853 | MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); | 1865 | MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); |
| 1854 | MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); | 1866 | MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); |
| @@ -1856,7 +1868,8 @@ MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>"); | |||
| 1856 | MODULE_LICENSE("GPL"); | 1868 | MODULE_LICENSE("GPL"); |
| 1857 | MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); | 1869 | MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); |
| 1858 | 1870 | ||
| 1859 | struct rtl_global_var global_var = {}; | 1871 | struct rtl_global_var rtl_global_var = {}; |
| 1872 | EXPORT_SYMBOL_GPL(rtl_global_var); | ||
| 1860 | 1873 | ||
| 1861 | static int __init rtl_core_module_init(void) | 1874 | static int __init rtl_core_module_init(void) |
| 1862 | { | 1875 | { |
| @@ -1864,8 +1877,8 @@ static int __init rtl_core_module_init(void) | |||
| 1864 | pr_err("Unable to register rtl_rc, use default RC !!\n"); | 1877 | pr_err("Unable to register rtl_rc, use default RC !!\n"); |
| 1865 | 1878 | ||
| 1866 | /* init some global vars */ | 1879 | /* init some global vars */ |
| 1867 | INIT_LIST_HEAD(&global_var.glb_priv_list); | 1880 | INIT_LIST_HEAD(&rtl_global_var.glb_priv_list); |
| 1868 | spin_lock_init(&global_var.glb_list_lock); | 1881 | spin_lock_init(&rtl_global_var.glb_list_lock); |
| 1869 | 1882 | ||
| 1870 | return 0; | 1883 | return 0; |
| 1871 | } | 1884 | } |
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index 8576bc34b032..0e5fe0902daf 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h | |||
| @@ -147,7 +147,7 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); | |||
| 147 | u8 rtl_tid_to_ac(u8 tid); | 147 | u8 rtl_tid_to_ac(u8 tid); |
| 148 | extern struct attribute_group rtl_attribute_group; | 148 | extern struct attribute_group rtl_attribute_group; |
| 149 | void rtl_easy_concurrent_retrytimer_callback(unsigned long data); | 149 | void rtl_easy_concurrent_retrytimer_callback(unsigned long data); |
| 150 | extern struct rtl_global_var global_var; | 150 | extern struct rtl_global_var rtl_global_var; |
| 151 | int rtlwifi_rate_mapping(struct ieee80211_hw *hw, | 151 | int rtlwifi_rate_mapping(struct ieee80211_hw *hw, |
| 152 | bool isht, u8 desc_rate, bool first_ampdu); | 152 | bool isht, u8 desc_rate, bool first_ampdu); |
| 153 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); | 153 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index ee84844be008..733b7ce7f0e2 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
| @@ -1330,3 +1330,4 @@ const struct ieee80211_ops rtl_ops = { | |||
| 1330 | .rfkill_poll = rtl_op_rfkill_poll, | 1330 | .rfkill_poll = rtl_op_rfkill_poll, |
| 1331 | .flush = rtl_op_flush, | 1331 | .flush = rtl_op_flush, |
| 1332 | }; | 1332 | }; |
| 1333 | EXPORT_SYMBOL_GPL(rtl_ops); | ||
diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c index 7d52d3d7769f..76e2086e137e 100644 --- a/drivers/net/wireless/rtlwifi/debug.c +++ b/drivers/net/wireless/rtlwifi/debug.c | |||
| @@ -51,3 +51,4 @@ void rtl_dbgp_flag_init(struct ieee80211_hw *hw) | |||
| 51 | 51 | ||
| 52 | /*Init Debug flag enable condition */ | 52 | /*Init Debug flag enable condition */ |
| 53 | } | 53 | } |
| 54 | EXPORT_SYMBOL_GPL(rtl_dbgp_flag_init); | ||
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 9e3894178e77..838a1ed3f194 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c | |||
| @@ -229,6 +229,7 @@ void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf) | |||
| 229 | 229 | ||
| 230 | *pbuf = (u8) (value32 & 0xff); | 230 | *pbuf = (u8) (value32 & 0xff); |
| 231 | } | 231 | } |
| 232 | EXPORT_SYMBOL_GPL(read_efuse_byte); | ||
| 232 | 233 | ||
| 233 | void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | 234 | void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) |
| 234 | { | 235 | { |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index c97e9d327331..703f839af6ca 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
| @@ -35,6 +35,13 @@ | |||
| 35 | #include "efuse.h" | 35 | #include "efuse.h" |
| 36 | #include <linux/export.h> | 36 | #include <linux/export.h> |
| 37 | #include <linux/kmemleak.h> | 37 | #include <linux/kmemleak.h> |
| 38 | #include <linux/module.h> | ||
| 39 | |||
| 40 | MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); | ||
| 41 | MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); | ||
| 42 | MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>"); | ||
| 43 | MODULE_LICENSE("GPL"); | ||
| 44 | MODULE_DESCRIPTION("PCI basic driver for rtlwifi"); | ||
| 38 | 45 | ||
| 39 | static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { | 46 | static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { |
| 40 | PCI_VENDOR_ID_INTEL, | 47 | PCI_VENDOR_ID_INTEL, |
| @@ -1008,19 +1015,6 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | |||
| 1008 | return; | 1015 | return; |
| 1009 | } | 1016 | } |
| 1010 | 1017 | ||
| 1011 | static void rtl_lps_change_work_callback(struct work_struct *work) | ||
| 1012 | { | ||
| 1013 | struct rtl_works *rtlworks = | ||
| 1014 | container_of(work, struct rtl_works, lps_change_work); | ||
| 1015 | struct ieee80211_hw *hw = rtlworks->hw; | ||
| 1016 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
| 1017 | |||
| 1018 | if (rtlpriv->enter_ps) | ||
| 1019 | rtl_lps_enter(hw); | ||
| 1020 | else | ||
| 1021 | rtl_lps_leave(hw); | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) | 1018 | static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) |
| 1025 | { | 1019 | { |
| 1026 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 1020 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
| @@ -1899,7 +1893,7 @@ int rtl_pci_probe(struct pci_dev *pdev, | |||
| 1899 | rtlpriv->rtlhal.interface = INTF_PCI; | 1893 | rtlpriv->rtlhal.interface = INTF_PCI; |
| 1900 | rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); | 1894 | rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); |
| 1901 | rtlpriv->intf_ops = &rtl_pci_ops; | 1895 | rtlpriv->intf_ops = &rtl_pci_ops; |
| 1902 | rtlpriv->glb_var = &global_var; | 1896 | rtlpriv->glb_var = &rtl_global_var; |
| 1903 | 1897 | ||
| 1904 | /* | 1898 | /* |
| 1905 | *init dbgp flags before all | 1899 | *init dbgp flags before all |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 884bceae38a9..298b615964e8 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
| @@ -269,6 +269,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) | |||
| 269 | 269 | ||
| 270 | spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags); | 270 | spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags); |
| 271 | } | 271 | } |
| 272 | EXPORT_SYMBOL_GPL(rtl_ips_nic_on); | ||
| 272 | 273 | ||
| 273 | /*for FW LPS*/ | 274 | /*for FW LPS*/ |
| 274 | 275 | ||
| @@ -518,6 +519,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) | |||
| 518 | "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); | 519 | "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); |
| 519 | } | 520 | } |
| 520 | } | 521 | } |
| 522 | EXPORT_SYMBOL_GPL(rtl_swlps_beacon); | ||
| 521 | 523 | ||
| 522 | void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | 524 | void rtl_swlps_rf_awake(struct ieee80211_hw *hw) |
| 523 | { | 525 | { |
| @@ -611,6 +613,19 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
| 611 | MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40)); | 613 | MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40)); |
| 612 | } | 614 | } |
| 613 | 615 | ||
| 616 | void rtl_lps_change_work_callback(struct work_struct *work) | ||
| 617 | { | ||
| 618 | struct rtl_works *rtlworks = | ||
| 619 | container_of(work, struct rtl_works, lps_change_work); | ||
| 620 | struct ieee80211_hw *hw = rtlworks->hw; | ||
| 621 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
| 622 | |||
| 623 | if (rtlpriv->enter_ps) | ||
| 624 | rtl_lps_enter(hw); | ||
| 625 | else | ||
| 626 | rtl_lps_leave(hw); | ||
| 627 | } | ||
| 628 | EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback); | ||
| 614 | 629 | ||
| 615 | void rtl_swlps_wq_callback(void *data) | 630 | void rtl_swlps_wq_callback(void *data) |
| 616 | { | 631 | { |
| @@ -922,3 +937,4 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) | |||
| 922 | else | 937 | else |
| 923 | rtl_p2p_noa_ie(hw, data, len - FCS_LEN); | 938 | rtl_p2p_noa_ie(hw, data, len - FCS_LEN); |
| 924 | } | 939 | } |
| 940 | EXPORT_SYMBOL_GPL(rtl_p2p_info); | ||
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index 4d682b753f50..88bd76ea88f7 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h | |||
| @@ -49,5 +49,6 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw); | |||
| 49 | void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); | 49 | void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); |
| 50 | void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); | 50 | void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); |
| 51 | void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len); | 51 | void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len); |
| 52 | void rtl_lps_change_work_callback(struct work_struct *work); | ||
| 52 | 53 | ||
| 53 | #endif | 54 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index a3532e077871..e56778cac9bf 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
| @@ -32,6 +32,13 @@ | |||
| 32 | #include "ps.h" | 32 | #include "ps.h" |
| 33 | #include "rtl8192c/fw_common.h" | 33 | #include "rtl8192c/fw_common.h" |
| 34 | #include <linux/export.h> | 34 | #include <linux/export.h> |
| 35 | #include <linux/module.h> | ||
| 36 | |||
| 37 | MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); | ||
| 38 | MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); | ||
| 39 | MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>"); | ||
| 40 | MODULE_LICENSE("GPL"); | ||
| 41 | MODULE_DESCRIPTION("USB basic driver for rtlwifi"); | ||
| 35 | 42 | ||
| 36 | #define REALTEK_USB_VENQT_READ 0xC0 | 43 | #define REALTEK_USB_VENQT_READ 0xC0 |
| 37 | #define REALTEK_USB_VENQT_WRITE 0x40 | 44 | #define REALTEK_USB_VENQT_WRITE 0x40 |
| @@ -1070,6 +1077,8 @@ int rtl_usb_probe(struct usb_interface *intf, | |||
| 1070 | spin_lock_init(&rtlpriv->locks.usb_lock); | 1077 | spin_lock_init(&rtlpriv->locks.usb_lock); |
| 1071 | INIT_WORK(&rtlpriv->works.fill_h2c_cmd, | 1078 | INIT_WORK(&rtlpriv->works.fill_h2c_cmd, |
| 1072 | rtl_fill_h2c_cmd_work_callback); | 1079 | rtl_fill_h2c_cmd_work_callback); |
| 1080 | INIT_WORK(&rtlpriv->works.lps_change_work, | ||
| 1081 | rtl_lps_change_work_callback); | ||
| 1073 | 1082 | ||
| 1074 | rtlpriv->usb_data_index = 0; | 1083 | rtlpriv->usb_data_index = 0; |
| 1075 | init_completion(&rtlpriv->firmware_loading_complete); | 1084 | init_completion(&rtlpriv->firmware_loading_complete); |
