.. | .. |
---|
106 | 106 | |
---|
107 | 107 | switch (qnum) { |
---|
108 | 108 | case 0: |
---|
109 | | - TX_QSTAT_INC(IEEE80211_AC_VO); |
---|
| 109 | + TX_QSTAT_INC(priv, IEEE80211_AC_VO); |
---|
110 | 110 | epid = priv->data_vo_ep; |
---|
111 | 111 | break; |
---|
112 | 112 | case 1: |
---|
113 | | - TX_QSTAT_INC(IEEE80211_AC_VI); |
---|
| 113 | + TX_QSTAT_INC(priv, IEEE80211_AC_VI); |
---|
114 | 114 | epid = priv->data_vi_ep; |
---|
115 | 115 | break; |
---|
116 | 116 | case 2: |
---|
117 | | - TX_QSTAT_INC(IEEE80211_AC_BE); |
---|
| 117 | + TX_QSTAT_INC(priv, IEEE80211_AC_BE); |
---|
118 | 118 | epid = priv->data_be_ep; |
---|
119 | 119 | break; |
---|
120 | 120 | case 3: |
---|
121 | 121 | default: |
---|
122 | | - TX_QSTAT_INC(IEEE80211_AC_BK); |
---|
| 122 | + TX_QSTAT_INC(priv, IEEE80211_AC_BK); |
---|
123 | 123 | epid = priv->data_bk_ep; |
---|
124 | 124 | break; |
---|
125 | 125 | } |
---|
.. | .. |
---|
323 | 323 | memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); |
---|
324 | 324 | |
---|
325 | 325 | if (is_cab) { |
---|
326 | | - CAB_STAT_INC; |
---|
| 326 | + CAB_STAT_INC(priv); |
---|
327 | 327 | tx_ctl->epid = priv->cab_ep; |
---|
328 | 328 | return; |
---|
329 | 329 | } |
---|
.. | .. |
---|
570 | 570 | spin_unlock_bh(&priv->tx.tx_lock); |
---|
571 | 571 | } |
---|
572 | 572 | |
---|
573 | | -void ath9k_tx_failed_tasklet(unsigned long data) |
---|
| 573 | +void ath9k_tx_failed_tasklet(struct tasklet_struct *t) |
---|
574 | 574 | { |
---|
575 | | - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; |
---|
| 575 | + struct ath9k_htc_priv *priv = from_tasklet(priv, t, tx_failed_tasklet); |
---|
576 | 576 | |
---|
577 | | - spin_lock_bh(&priv->tx.tx_lock); |
---|
| 577 | + spin_lock(&priv->tx.tx_lock); |
---|
578 | 578 | if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { |
---|
579 | | - spin_unlock_bh(&priv->tx.tx_lock); |
---|
| 579 | + spin_unlock(&priv->tx.tx_lock); |
---|
580 | 580 | return; |
---|
581 | 581 | } |
---|
582 | | - spin_unlock_bh(&priv->tx.tx_lock); |
---|
| 582 | + spin_unlock(&priv->tx.tx_lock); |
---|
583 | 583 | |
---|
584 | 584 | ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); |
---|
585 | 585 | } |
---|
.. | .. |
---|
808 | 808 | skb_queue_head_init(&priv->tx.data_vi_queue); |
---|
809 | 809 | skb_queue_head_init(&priv->tx.data_vo_queue); |
---|
810 | 810 | skb_queue_head_init(&priv->tx.tx_failed); |
---|
| 811 | + |
---|
| 812 | + /* Allow ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) to operate. */ |
---|
| 813 | + smp_wmb(); |
---|
| 814 | + priv->tx.initialized = true; |
---|
| 815 | + |
---|
811 | 816 | return 0; |
---|
812 | 817 | } |
---|
813 | 818 | |
---|
.. | .. |
---|
893 | 898 | if (priv->rxfilter & FIF_PSPOLL) |
---|
894 | 899 | rfilt |= ATH9K_RX_FILTER_PSPOLL; |
---|
895 | 900 | |
---|
896 | | - if (priv->nvifs > 1 || priv->rxfilter & FIF_OTHER_BSS) |
---|
| 901 | + if (priv->nvifs > 1 || |
---|
| 902 | + priv->rxfilter & (FIF_OTHER_BSS | FIF_MCAST_ACTION)) |
---|
897 | 903 | rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; |
---|
898 | 904 | |
---|
899 | 905 | return rfilt; |
---|
.. | .. |
---|
1005 | 1011 | goto rx_next; |
---|
1006 | 1012 | } |
---|
1007 | 1013 | |
---|
| 1014 | + if (rxstatus->rs_keyix >= ATH_KEYMAX && |
---|
| 1015 | + rxstatus->rs_keyix != ATH9K_RXKEYIX_INVALID) { |
---|
| 1016 | + ath_dbg(common, ANY, |
---|
| 1017 | + "Invalid keyix, dropping (keyix: %d)\n", |
---|
| 1018 | + rxstatus->rs_keyix); |
---|
| 1019 | + goto rx_next; |
---|
| 1020 | + } |
---|
| 1021 | + |
---|
1008 | 1022 | /* Get the RX status information */ |
---|
1009 | 1023 | |
---|
1010 | 1024 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); |
---|
.. | .. |
---|
1061 | 1075 | /* |
---|
1062 | 1076 | * FIXME: Handle FLUSH later on. |
---|
1063 | 1077 | */ |
---|
1064 | | -void ath9k_rx_tasklet(unsigned long data) |
---|
| 1078 | +void ath9k_rx_tasklet(struct tasklet_struct *t) |
---|
1065 | 1079 | { |
---|
1066 | | - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; |
---|
| 1080 | + struct ath9k_htc_priv *priv = from_tasklet(priv, t, rx_tasklet); |
---|
1067 | 1081 | struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; |
---|
1068 | 1082 | struct ieee80211_rx_status rx_status; |
---|
1069 | 1083 | struct sk_buff *skb; |
---|
.. | .. |
---|
1124 | 1138 | struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; |
---|
1125 | 1139 | unsigned long flags; |
---|
1126 | 1140 | |
---|
| 1141 | + /* Check if ath9k_rx_init() completed. */ |
---|
| 1142 | + if (!data_race(priv->rx.initialized)) |
---|
| 1143 | + goto err; |
---|
| 1144 | + |
---|
1127 | 1145 | spin_lock_irqsave(&priv->rx.rxbuflock, flags); |
---|
1128 | 1146 | list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) { |
---|
1129 | 1147 | if (!tmp_buf->in_process) { |
---|
.. | .. |
---|
1179 | 1197 | list_add_tail(&rxbuf->list, &priv->rx.rxbuf); |
---|
1180 | 1198 | } |
---|
1181 | 1199 | |
---|
| 1200 | + /* Allow ath9k_htc_rxep() to operate. */ |
---|
| 1201 | + smp_wmb(); |
---|
| 1202 | + priv->rx.initialized = true; |
---|
| 1203 | + |
---|
1182 | 1204 | return 0; |
---|
1183 | 1205 | |
---|
1184 | 1206 | err: |
---|