diff options
110 files changed, 3829 insertions, 2962 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 6d7105b7e8f1..7cf4317a2a84 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -123,14 +123,7 @@ struct ath_ops { | |||
123 | }; | 123 | }; |
124 | 124 | ||
125 | struct ath_common; | 125 | struct ath_common; |
126 | 126 | struct ath_bus_ops; | |
127 | struct ath_bus_ops { | ||
128 | enum ath_bus_type ath_bus_type; | ||
129 | void (*read_cachesize)(struct ath_common *common, int *csz); | ||
130 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | ||
131 | void (*bt_coex_prep)(struct ath_common *common); | ||
132 | void (*extn_synch_en)(struct ath_common *common); | ||
133 | }; | ||
134 | 127 | ||
135 | struct ath_common { | 128 | struct ath_common { |
136 | void *ah; | 129 | void *ah; |
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 82324e98efef..ea9982781559 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/nl80211.h> | 19 | #include <linux/nl80211.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/etherdevice.h> | ||
21 | #include <ar231x_platform.h> | 22 | #include <ar231x_platform.h> |
22 | #include "ath5k.h" | 23 | #include "ath5k.h" |
23 | #include "debug.h" | 24 | #include "debug.h" |
@@ -62,10 +63,27 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) | |||
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
64 | 65 | ||
66 | static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
67 | { | ||
68 | struct ath5k_softc *sc = ah->ah_sc; | ||
69 | struct platform_device *pdev = to_platform_device(sc->dev); | ||
70 | struct ar231x_board_config *bcfg = pdev->dev.platform_data; | ||
71 | u8 *cfg_mac; | ||
72 | |||
73 | if (to_platform_device(sc->dev)->id == 0) | ||
74 | cfg_mac = bcfg->config->wlan0_mac; | ||
75 | else | ||
76 | cfg_mac = bcfg->config->wlan1_mac; | ||
77 | |||
78 | memcpy(mac, cfg_mac, ETH_ALEN); | ||
79 | return 0; | ||
80 | } | ||
81 | |||
65 | static const struct ath_bus_ops ath_ahb_bus_ops = { | 82 | static const struct ath_bus_ops ath_ahb_bus_ops = { |
66 | .ath_bus_type = ATH_AHB, | 83 | .ath_bus_type = ATH_AHB, |
67 | .read_cachesize = ath5k_ahb_read_cachesize, | 84 | .read_cachesize = ath5k_ahb_read_cachesize, |
68 | .eeprom_read = ath5k_ahb_eeprom_read, | 85 | .eeprom_read = ath5k_ahb_eeprom_read, |
86 | .eeprom_read_mac = ath5k_ahb_eeprom_read_mac, | ||
69 | }; | 87 | }; |
70 | 88 | ||
71 | /*Initialization*/ | 89 | /*Initialization*/ |
@@ -142,6 +160,16 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
142 | else | 160 | else |
143 | reg |= AR5K_AR5312_ENABLE_WLAN1; | 161 | reg |= AR5K_AR5312_ENABLE_WLAN1; |
144 | __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); | 162 | __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); |
163 | |||
164 | /* | ||
165 | * On a dual-band AR5312, the multiband radio is only | ||
166 | * used as pass-through. Disable 2 GHz support in the | ||
167 | * driver for it | ||
168 | */ | ||
169 | if (to_platform_device(sc->dev)->id == 0 && | ||
170 | (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) == | ||
171 | (BD_WLAN1|BD_WLAN0)) | ||
172 | __set_bit(ATH_STAT_2G_DISABLED, sc->status); | ||
145 | } | 173 | } |
146 | 174 | ||
147 | ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); | 175 | ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 8a06dbd39629..bb50700436fe 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -224,8 +224,7 @@ | |||
224 | 224 | ||
225 | /* SIFS */ | 225 | /* SIFS */ |
226 | #define AR5K_INIT_SIFS_TURBO 6 | 226 | #define AR5K_INIT_SIFS_TURBO 6 |
227 | /* XXX: 8 from initvals 10 from standard */ | 227 | #define AR5K_INIT_SIFS_DEFAULT_BG 10 |
228 | #define AR5K_INIT_SIFS_DEFAULT_BG 8 | ||
229 | #define AR5K_INIT_SIFS_DEFAULT_A 16 | 228 | #define AR5K_INIT_SIFS_DEFAULT_A 16 |
230 | #define AR5K_INIT_SIFS_HALF_RATE 32 | 229 | #define AR5K_INIT_SIFS_HALF_RATE 32 |
231 | #define AR5K_INIT_SIFS_QUARTER_RATE 64 | 230 | #define AR5K_INIT_SIFS_QUARTER_RATE 64 |
@@ -453,12 +452,10 @@ struct ath5k_tx_status { | |||
453 | u16 ts_seqnum; | 452 | u16 ts_seqnum; |
454 | u16 ts_tstamp; | 453 | u16 ts_tstamp; |
455 | u8 ts_status; | 454 | u8 ts_status; |
456 | u8 ts_rate[4]; | ||
457 | u8 ts_retry[4]; | ||
458 | u8 ts_final_idx; | 455 | u8 ts_final_idx; |
456 | u8 ts_final_retry; | ||
459 | s8 ts_rssi; | 457 | s8 ts_rssi; |
460 | u8 ts_shortretry; | 458 | u8 ts_shortretry; |
461 | u8 ts_longretry; | ||
462 | u8 ts_virtcol; | 459 | u8 ts_virtcol; |
463 | u8 ts_antenna; | 460 | u8 ts_antenna; |
464 | }; | 461 | }; |
@@ -875,6 +872,19 @@ enum ath5k_int { | |||
875 | AR5K_INT_QTRIG = 0x40000000, /* Non common */ | 872 | AR5K_INT_QTRIG = 0x40000000, /* Non common */ |
876 | AR5K_INT_GLOBAL = 0x80000000, | 873 | AR5K_INT_GLOBAL = 0x80000000, |
877 | 874 | ||
875 | AR5K_INT_TX_ALL = AR5K_INT_TXOK | ||
876 | | AR5K_INT_TXDESC | ||
877 | | AR5K_INT_TXERR | ||
878 | | AR5K_INT_TXEOL | ||
879 | | AR5K_INT_TXURN, | ||
880 | |||
881 | AR5K_INT_RX_ALL = AR5K_INT_RXOK | ||
882 | | AR5K_INT_RXDESC | ||
883 | | AR5K_INT_RXERR | ||
884 | | AR5K_INT_RXNOFRM | ||
885 | | AR5K_INT_RXEOL | ||
886 | | AR5K_INT_RXORN, | ||
887 | |||
878 | AR5K_INT_COMMON = AR5K_INT_RXOK | 888 | AR5K_INT_COMMON = AR5K_INT_RXOK |
879 | | AR5K_INT_RXDESC | 889 | | AR5K_INT_RXDESC |
880 | | AR5K_INT_RXERR | 890 | | AR5K_INT_RXERR |
@@ -1058,6 +1068,7 @@ struct ath5k_hw { | |||
1058 | u8 ah_coverage_class; | 1068 | u8 ah_coverage_class; |
1059 | bool ah_ack_bitrate_high; | 1069 | bool ah_ack_bitrate_high; |
1060 | u8 ah_bwmode; | 1070 | u8 ah_bwmode; |
1071 | bool ah_short_slot; | ||
1061 | 1072 | ||
1062 | /* Antenna Control */ | 1073 | /* Antenna Control */ |
1063 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; | 1074 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; |
@@ -1144,6 +1155,13 @@ struct ath5k_hw { | |||
1144 | struct ath5k_rx_status *); | 1155 | struct ath5k_rx_status *); |
1145 | }; | 1156 | }; |
1146 | 1157 | ||
1158 | struct ath_bus_ops { | ||
1159 | enum ath_bus_type ath_bus_type; | ||
1160 | void (*read_cachesize)(struct ath_common *common, int *csz); | ||
1161 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | ||
1162 | int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac); | ||
1163 | }; | ||
1164 | |||
1147 | /* | 1165 | /* |
1148 | * Prototypes | 1166 | * Prototypes |
1149 | */ | 1167 | */ |
@@ -1227,13 +1245,12 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah); | |||
1227 | /* EEPROM access functions */ | 1245 | /* EEPROM access functions */ |
1228 | int ath5k_eeprom_init(struct ath5k_hw *ah); | 1246 | int ath5k_eeprom_init(struct ath5k_hw *ah); |
1229 | void ath5k_eeprom_detach(struct ath5k_hw *ah); | 1247 | void ath5k_eeprom_detach(struct ath5k_hw *ah); |
1230 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); | ||
1231 | 1248 | ||
1232 | 1249 | ||
1233 | /* Protocol Control Unit Functions */ | 1250 | /* Protocol Control Unit Functions */ |
1234 | /* Helpers */ | 1251 | /* Helpers */ |
1235 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | 1252 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, |
1236 | int len, struct ieee80211_rate *rate); | 1253 | int len, struct ieee80211_rate *rate, bool shortpre); |
1237 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); | 1254 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); |
1238 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); | 1255 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); |
1239 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); | 1256 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index bc8240560488..1588401de3c4 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -313,12 +313,17 @@ int ath5k_hw_init(struct ath5k_softc *sc) | |||
313 | goto err; | 313 | goto err; |
314 | } | 314 | } |
315 | 315 | ||
316 | if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) { | ||
317 | __clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode); | ||
318 | __clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode); | ||
319 | } | ||
320 | |||
316 | /* Crypto settings */ | 321 | /* Crypto settings */ |
317 | common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? | 322 | common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? |
318 | AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); | 323 | AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); |
319 | 324 | ||
320 | if (srev >= AR5K_SREV_AR5212_V4 && | 325 | if (srev >= AR5K_SREV_AR5212_V4 && |
321 | (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && | 326 | (ee->ee_version < AR5K_EEPROM_VERSION_5_0 || |
322 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) | 327 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) |
323 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; | 328 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; |
324 | 329 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4d7f21ee111c..7583841fc29a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1444,6 +1444,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) | |||
1444 | } | 1444 | } |
1445 | 1445 | ||
1446 | static void | 1446 | static void |
1447 | ath5k_set_current_imask(struct ath5k_softc *sc) | ||
1448 | { | ||
1449 | enum ath5k_int imask = sc->imask; | ||
1450 | unsigned long flags; | ||
1451 | |||
1452 | spin_lock_irqsave(&sc->irqlock, flags); | ||
1453 | if (sc->rx_pending) | ||
1454 | imask &= ~AR5K_INT_RX_ALL; | ||
1455 | if (sc->tx_pending) | ||
1456 | imask &= ~AR5K_INT_TX_ALL; | ||
1457 | ath5k_hw_set_imr(sc->ah, imask); | ||
1458 | spin_unlock_irqrestore(&sc->irqlock, flags); | ||
1459 | } | ||
1460 | |||
1461 | static void | ||
1447 | ath5k_tasklet_rx(unsigned long data) | 1462 | ath5k_tasklet_rx(unsigned long data) |
1448 | { | 1463 | { |
1449 | struct ath5k_rx_status rs = {}; | 1464 | struct ath5k_rx_status rs = {}; |
@@ -1506,6 +1521,8 @@ next: | |||
1506 | } while (ath5k_rxbuf_setup(sc, bf) == 0); | 1521 | } while (ath5k_rxbuf_setup(sc, bf) == 0); |
1507 | unlock: | 1522 | unlock: |
1508 | spin_unlock(&sc->rxbuflock); | 1523 | spin_unlock(&sc->rxbuflock); |
1524 | sc->rx_pending = false; | ||
1525 | ath5k_set_current_imask(sc); | ||
1509 | } | 1526 | } |
1510 | 1527 | ||
1511 | 1528 | ||
@@ -1573,28 +1590,28 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1573 | struct ath5k_txq *txq, struct ath5k_tx_status *ts) | 1590 | struct ath5k_txq *txq, struct ath5k_tx_status *ts) |
1574 | { | 1591 | { |
1575 | struct ieee80211_tx_info *info; | 1592 | struct ieee80211_tx_info *info; |
1593 | u8 tries[3]; | ||
1576 | int i; | 1594 | int i; |
1577 | 1595 | ||
1578 | sc->stats.tx_all_count++; | 1596 | sc->stats.tx_all_count++; |
1579 | sc->stats.tx_bytes_count += skb->len; | 1597 | sc->stats.tx_bytes_count += skb->len; |
1580 | info = IEEE80211_SKB_CB(skb); | 1598 | info = IEEE80211_SKB_CB(skb); |
1581 | 1599 | ||
1600 | tries[0] = info->status.rates[0].count; | ||
1601 | tries[1] = info->status.rates[1].count; | ||
1602 | tries[2] = info->status.rates[2].count; | ||
1603 | |||
1582 | ieee80211_tx_info_clear_status(info); | 1604 | ieee80211_tx_info_clear_status(info); |
1583 | for (i = 0; i < 4; i++) { | 1605 | |
1606 | for (i = 0; i < ts->ts_final_idx; i++) { | ||
1584 | struct ieee80211_tx_rate *r = | 1607 | struct ieee80211_tx_rate *r = |
1585 | &info->status.rates[i]; | 1608 | &info->status.rates[i]; |
1586 | 1609 | ||
1587 | if (ts->ts_rate[i]) { | 1610 | r->count = tries[i]; |
1588 | r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]); | ||
1589 | r->count = ts->ts_retry[i]; | ||
1590 | } else { | ||
1591 | r->idx = -1; | ||
1592 | r->count = 0; | ||
1593 | } | ||
1594 | } | 1611 | } |
1595 | 1612 | ||
1596 | /* count the successful attempt as well */ | 1613 | info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry; |
1597 | info->status.rates[ts->ts_final_idx].count++; | 1614 | info->status.rates[ts->ts_final_idx + 1].idx = -1; |
1598 | 1615 | ||
1599 | if (unlikely(ts->ts_status)) { | 1616 | if (unlikely(ts->ts_status)) { |
1600 | sc->stats.ack_fail++; | 1617 | sc->stats.ack_fail++; |
@@ -1609,6 +1626,9 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1609 | } else { | 1626 | } else { |
1610 | info->flags |= IEEE80211_TX_STAT_ACK; | 1627 | info->flags |= IEEE80211_TX_STAT_ACK; |
1611 | info->status.ack_signal = ts->ts_rssi; | 1628 | info->status.ack_signal = ts->ts_rssi; |
1629 | |||
1630 | /* count the successful attempt as well */ | ||
1631 | info->status.rates[ts->ts_final_idx].count++; | ||
1612 | } | 1632 | } |
1613 | 1633 | ||
1614 | /* | 1634 | /* |
@@ -1690,6 +1710,9 @@ ath5k_tasklet_tx(unsigned long data) | |||
1690 | for (i=0; i < AR5K_NUM_TX_QUEUES; i++) | 1710 | for (i=0; i < AR5K_NUM_TX_QUEUES; i++) |
1691 | if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) | 1711 | if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) |
1692 | ath5k_tx_processq(sc, &sc->txqs[i]); | 1712 | ath5k_tx_processq(sc, &sc->txqs[i]); |
1713 | |||
1714 | sc->tx_pending = false; | ||
1715 | ath5k_set_current_imask(sc); | ||
1693 | } | 1716 | } |
1694 | 1717 | ||
1695 | 1718 | ||
@@ -2119,6 +2142,20 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah) | |||
2119 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ | 2142 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ |
2120 | } | 2143 | } |
2121 | 2144 | ||
2145 | static void | ||
2146 | ath5k_schedule_rx(struct ath5k_softc *sc) | ||
2147 | { | ||
2148 | sc->rx_pending = true; | ||
2149 | tasklet_schedule(&sc->rxtq); | ||
2150 | } | ||
2151 | |||
2152 | static void | ||
2153 | ath5k_schedule_tx(struct ath5k_softc *sc) | ||
2154 | { | ||
2155 | sc->tx_pending = true; | ||
2156 | tasklet_schedule(&sc->txtq); | ||
2157 | } | ||
2158 | |||
2122 | irqreturn_t | 2159 | irqreturn_t |
2123 | ath5k_intr(int irq, void *dev_id) | 2160 | ath5k_intr(int irq, void *dev_id) |
2124 | { | 2161 | { |
@@ -2161,7 +2198,7 @@ ath5k_intr(int irq, void *dev_id) | |||
2161 | ieee80211_queue_work(sc->hw, &sc->reset_work); | 2198 | ieee80211_queue_work(sc->hw, &sc->reset_work); |
2162 | } | 2199 | } |
2163 | else | 2200 | else |
2164 | tasklet_schedule(&sc->rxtq); | 2201 | ath5k_schedule_rx(sc); |
2165 | } else { | 2202 | } else { |
2166 | if (status & AR5K_INT_SWBA) { | 2203 | if (status & AR5K_INT_SWBA) { |
2167 | tasklet_hi_schedule(&sc->beacontq); | 2204 | tasklet_hi_schedule(&sc->beacontq); |
@@ -2179,10 +2216,10 @@ ath5k_intr(int irq, void *dev_id) | |||
2179 | ath5k_hw_update_tx_triglevel(ah, true); | 2216 | ath5k_hw_update_tx_triglevel(ah, true); |
2180 | } | 2217 | } |
2181 | if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) | 2218 | if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) |
2182 | tasklet_schedule(&sc->rxtq); | 2219 | ath5k_schedule_rx(sc); |
2183 | if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC | 2220 | if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC |
2184 | | AR5K_INT_TXERR | AR5K_INT_TXEOL)) | 2221 | | AR5K_INT_TXERR | AR5K_INT_TXEOL)) |
2185 | tasklet_schedule(&sc->txtq); | 2222 | ath5k_schedule_tx(sc); |
2186 | if (status & AR5K_INT_BMISS) { | 2223 | if (status & AR5K_INT_BMISS) { |
2187 | /* TODO */ | 2224 | /* TODO */ |
2188 | } | 2225 | } |
@@ -2201,6 +2238,9 @@ ath5k_intr(int irq, void *dev_id) | |||
2201 | 2238 | ||
2202 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); | 2239 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); |
2203 | 2240 | ||
2241 | if (sc->rx_pending || sc->tx_pending) | ||
2242 | ath5k_set_current_imask(sc); | ||
2243 | |||
2204 | if (unlikely(!counter)) | 2244 | if (unlikely(!counter)) |
2205 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); | 2245 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); |
2206 | 2246 | ||
@@ -2572,6 +2612,8 @@ done: | |||
2572 | 2612 | ||
2573 | static void stop_tasklets(struct ath5k_softc *sc) | 2613 | static void stop_tasklets(struct ath5k_softc *sc) |
2574 | { | 2614 | { |
2615 | sc->rx_pending = false; | ||
2616 | sc->tx_pending = false; | ||
2575 | tasklet_kill(&sc->rxtq); | 2617 | tasklet_kill(&sc->rxtq); |
2576 | tasklet_kill(&sc->txtq); | 2618 | tasklet_kill(&sc->txtq); |
2577 | tasklet_kill(&sc->calib); | 2619 | tasklet_kill(&sc->calib); |
@@ -2838,7 +2880,7 @@ ath5k_init(struct ieee80211_hw *hw) | |||
2838 | INIT_WORK(&sc->reset_work, ath5k_reset_work); | 2880 | INIT_WORK(&sc->reset_work, ath5k_reset_work); |
2839 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); | 2881 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); |
2840 | 2882 | ||
2841 | ret = ath5k_eeprom_read_mac(ah, mac); | 2883 | ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac); |
2842 | if (ret) { | 2884 | if (ret) { |
2843 | ATH5K_ERR(sc, "unable to read address from EEPROM\n"); | 2885 | ATH5K_ERR(sc, "unable to read address from EEPROM\n"); |
2844 | goto err_queues; | 2886 | goto err_queues; |
@@ -2898,7 +2940,6 @@ ath5k_deinit_softc(struct ath5k_softc *sc) | |||
2898 | * XXX: ??? detach ath5k_hw ??? | 2940 | * XXX: ??? detach ath5k_hw ??? |
2899 | * Other than that, it's straightforward... | 2941 | * Other than that, it's straightforward... |
2900 | */ | 2942 | */ |
2901 | ath5k_debug_finish_device(sc); | ||
2902 | ieee80211_unregister_hw(hw); | 2943 | ieee80211_unregister_hw(hw); |
2903 | ath5k_desc_free(sc); | 2944 | ath5k_desc_free(sc); |
2904 | ath5k_txq_release(sc); | 2945 | ath5k_txq_release(sc); |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 978f1f4ac2f3..b294f3305011 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -193,12 +193,13 @@ struct ath5k_softc { | |||
193 | dma_addr_t desc_daddr; /* DMA (physical) address */ | 193 | dma_addr_t desc_daddr; /* DMA (physical) address */ |
194 | size_t desc_len; /* size of TX/RX descriptors */ | 194 | size_t desc_len; /* size of TX/RX descriptors */ |
195 | 195 | ||
196 | DECLARE_BITMAP(status, 5); | 196 | DECLARE_BITMAP(status, 6); |
197 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ | 197 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ |
198 | #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ | 198 | #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ |
199 | #define ATH_STAT_PROMISC 2 | 199 | #define ATH_STAT_PROMISC 2 |
200 | #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ | 200 | #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ |
201 | #define ATH_STAT_STARTED 4 /* opened & irqs enabled */ | 201 | #define ATH_STAT_STARTED 4 /* opened & irqs enabled */ |
202 | #define ATH_STAT_2G_DISABLED 5 /* multiband radio without 2G */ | ||
202 | 203 | ||
203 | unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ | 204 | unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ |
204 | struct ieee80211_channel *curchan; /* current h/w channel */ | 205 | struct ieee80211_channel *curchan; /* current h/w channel */ |
@@ -207,6 +208,10 @@ struct ath5k_softc { | |||
207 | 208 | ||
208 | enum ath5k_int imask; /* interrupt mask copy */ | 209 | enum ath5k_int imask; /* interrupt mask copy */ |
209 | 210 | ||
211 | spinlock_t irqlock; | ||
212 | bool rx_pending; /* rx tasklet pending */ | ||
213 | bool tx_pending; /* tx tasklet pending */ | ||
214 | |||
210 | u8 lladdr[ETH_ALEN]; | 215 | u8 lladdr[ETH_ALEN]; |
211 | u8 bssidmask[ETH_ALEN]; | 216 | u8 bssidmask[ETH_ALEN]; |
212 | 217 | ||
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index f77e8a703c5c..7dd88e1c3ff8 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c | |||
@@ -94,6 +94,9 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112) | ||
98 | __clear_bit(AR5K_MODE_11A, caps->cap_mode); | ||
99 | |||
97 | /* Set number of supported TX queues */ | 100 | /* Set number of supported TX queues */ |
98 | if (ah->ah_version == AR5K_AR5210) | 101 | if (ah->ah_version == AR5K_AR5210) |
99 | caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; | 102 | caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; |
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 0230f30e9e9a..0bf7313b8a17 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -888,65 +888,38 @@ static const struct file_operations fops_queue = { | |||
888 | void | 888 | void |
889 | ath5k_debug_init_device(struct ath5k_softc *sc) | 889 | ath5k_debug_init_device(struct ath5k_softc *sc) |
890 | { | 890 | { |
891 | sc->debug.level = ath5k_debug; | 891 | struct dentry *phydir; |
892 | 892 | ||
893 | sc->debug.debugfs_phydir = debugfs_create_dir("ath5k", | 893 | sc->debug.level = ath5k_debug; |
894 | sc->hw->wiphy->debugfsdir); | ||
895 | 894 | ||
896 | sc->debug.debugfs_debug = debugfs_create_file("debug", | 895 | phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir); |
897 | S_IWUSR | S_IRUSR, | 896 | if (!phydir) |
898 | sc->debug.debugfs_phydir, sc, &fops_debug); | 897 | return; |
899 | 898 | ||
900 | sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR, | 899 | debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc, |
901 | sc->debug.debugfs_phydir, sc, &fops_registers); | 900 | &fops_debug); |
902 | 901 | ||
903 | sc->debug.debugfs_beacon = debugfs_create_file("beacon", | 902 | debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers); |
904 | S_IWUSR | S_IRUSR, | ||
905 | sc->debug.debugfs_phydir, sc, &fops_beacon); | ||
906 | 903 | ||
907 | sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, | 904 | debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc, |
908 | sc->debug.debugfs_phydir, sc, &fops_reset); | 905 | &fops_beacon); |
909 | 906 | ||
910 | sc->debug.debugfs_antenna = debugfs_create_file("antenna", | 907 | debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset); |
911 | S_IWUSR | S_IRUSR, | ||
912 | sc->debug.debugfs_phydir, sc, &fops_antenna); | ||
913 | 908 | ||
914 | sc->debug.debugfs_misc = debugfs_create_file("misc", | 909 | debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc, |
915 | S_IRUSR, | 910 | &fops_antenna); |
916 | sc->debug.debugfs_phydir, sc, &fops_misc); | ||
917 | 911 | ||
918 | sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", | 912 | debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc); |
919 | S_IWUSR | S_IRUSR, | ||
920 | sc->debug.debugfs_phydir, sc, | ||
921 | &fops_frameerrors); | ||
922 | 913 | ||
923 | sc->debug.debugfs_ani = debugfs_create_file("ani", | 914 | debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc, |
924 | S_IWUSR | S_IRUSR, | 915 | &fops_frameerrors); |
925 | sc->debug.debugfs_phydir, sc, | ||
926 | &fops_ani); | ||
927 | 916 | ||
928 | sc->debug.debugfs_queue = debugfs_create_file("queue", | 917 | debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani); |
929 | S_IWUSR | S_IRUSR, | ||
930 | sc->debug.debugfs_phydir, sc, | ||
931 | &fops_queue); | ||
932 | } | ||
933 | 918 | ||
934 | void | 919 | debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc, |
935 | ath5k_debug_finish_device(struct ath5k_softc *sc) | 920 | &fops_queue); |
936 | { | ||
937 | debugfs_remove(sc->debug.debugfs_debug); | ||
938 | debugfs_remove(sc->debug.debugfs_registers); | ||
939 | debugfs_remove(sc->debug.debugfs_beacon); | ||
940 | debugfs_remove(sc->debug.debugfs_reset); | ||
941 | debugfs_remove(sc->debug.debugfs_antenna); | ||
942 | debugfs_remove(sc->debug.debugfs_misc); | ||
943 | debugfs_remove(sc->debug.debugfs_frameerrors); | ||
944 | debugfs_remove(sc->debug.debugfs_ani); | ||
945 | debugfs_remove(sc->debug.debugfs_queue); | ||
946 | debugfs_remove(sc->debug.debugfs_phydir); | ||
947 | } | 921 | } |
948 | 922 | ||
949 | |||
950 | /* functions used in other places */ | 923 | /* functions used in other places */ |
951 | 924 | ||
952 | void | 925 | void |
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index b0355aef68d3..193dd2d4ea3c 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h | |||
@@ -68,17 +68,6 @@ struct ath5k_buf; | |||
68 | 68 | ||
69 | struct ath5k_dbg_info { | 69 | struct ath5k_dbg_info { |
70 | unsigned int level; /* debug level */ | 70 | unsigned int level; /* debug level */ |
71 | /* debugfs entries */ | ||
72 | struct dentry *debugfs_phydir; | ||
73 | struct dentry *debugfs_debug; | ||
74 | struct dentry *debugfs_registers; | ||
75 | struct dentry *debugfs_beacon; | ||
76 | struct dentry *debugfs_reset; | ||
77 | struct dentry *debugfs_antenna; | ||
78 | struct dentry *debugfs_misc; | ||
79 | struct dentry *debugfs_frameerrors; | ||
80 | struct dentry *debugfs_ani; | ||
81 | struct dentry *debugfs_queue; | ||
82 | }; | 71 | }; |
83 | 72 | ||
84 | /** | 73 | /** |
@@ -141,9 +130,6 @@ void | |||
141 | ath5k_debug_init_device(struct ath5k_softc *sc); | 130 | ath5k_debug_init_device(struct ath5k_softc *sc); |
142 | 131 | ||
143 | void | 132 | void |
144 | ath5k_debug_finish_device(struct ath5k_softc *sc); | ||
145 | |||
146 | void | ||
147 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); | 133 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); |
148 | 134 | ||
149 | void | 135 | void |
@@ -167,9 +153,6 @@ static inline void | |||
167 | ath5k_debug_init_device(struct ath5k_softc *sc) {} | 153 | ath5k_debug_init_device(struct ath5k_softc *sc) {} |
168 | 154 | ||
169 | static inline void | 155 | static inline void |
170 | ath5k_debug_finish_device(struct ath5k_softc *sc) {} | ||
171 | |||
172 | static inline void | ||
173 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} | 156 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} |
174 | 157 | ||
175 | static inline void | 158 | static inline void |
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 16b44ff7dd3e..dd7cd95c364a 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c | |||
@@ -185,6 +185,12 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
185 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | 185 | struct ath5k_hw_4w_tx_ctl *tx_ctl; |
186 | unsigned int frame_len; | 186 | unsigned int frame_len; |
187 | 187 | ||
188 | /* | ||
189 | * Use local variables for these to reduce load/store access on | ||
190 | * uncached memory | ||
191 | */ | ||
192 | u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; | ||
193 | |||
188 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | 194 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; |
189 | 195 | ||
190 | /* | 196 | /* |
@@ -208,8 +214,9 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
208 | if (tx_power > AR5K_TUNE_MAX_TXPOWER) | 214 | if (tx_power > AR5K_TUNE_MAX_TXPOWER) |
209 | tx_power = AR5K_TUNE_MAX_TXPOWER; | 215 | tx_power = AR5K_TUNE_MAX_TXPOWER; |
210 | 216 | ||
211 | /* Clear descriptor */ | 217 | /* Clear descriptor status area */ |
212 | memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); | 218 | memset(&desc->ud.ds_tx5212.tx_stat, 0, |
219 | sizeof(desc->ud.ds_tx5212.tx_stat)); | ||
213 | 220 | ||
214 | /* Setup control descriptor */ | 221 | /* Setup control descriptor */ |
215 | 222 | ||
@@ -221,7 +228,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
221 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) | 228 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) |
222 | return -EINVAL; | 229 | return -EINVAL; |
223 | 230 | ||
224 | tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; | 231 | txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; |
225 | 232 | ||
226 | /* Verify and set buffer length */ | 233 | /* Verify and set buffer length */ |
227 | 234 | ||
@@ -232,21 +239,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
232 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) | 239 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) |
233 | return -EINVAL; | 240 | return -EINVAL; |
234 | 241 | ||
235 | tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; | 242 | txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; |
236 | 243 | ||
237 | tx_ctl->tx_control_0 |= | 244 | txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | |
238 | AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | | 245 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); |
239 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); | 246 | txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); |
240 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, | 247 | txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); |
241 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); | 248 | txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; |
242 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0, | ||
243 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); | ||
244 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
245 | 249 | ||
246 | #define _TX_FLAGS(_c, _flag) \ | 250 | #define _TX_FLAGS(_c, _flag) \ |
247 | if (flags & AR5K_TXDESC_##_flag) { \ | 251 | if (flags & AR5K_TXDESC_##_flag) { \ |
248 | tx_ctl->tx_control_##_c |= \ | 252 | txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ |
249 | AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ | ||
250 | } | 253 | } |
251 | 254 | ||
252 | _TX_FLAGS(0, CLRDMASK); | 255 | _TX_FLAGS(0, CLRDMASK); |
@@ -262,8 +265,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
262 | * WEP crap | 265 | * WEP crap |
263 | */ | 266 | */ |
264 | if (key_index != AR5K_TXKEYIX_INVALID) { | 267 | if (key_index != AR5K_TXKEYIX_INVALID) { |
265 | tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; | 268 | txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; |
266 | tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, | 269 | txctl1 |= AR5K_REG_SM(key_index, |
267 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); | 270 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); |
268 | } | 271 | } |
269 | 272 | ||
@@ -274,12 +277,16 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
274 | if ((flags & AR5K_TXDESC_RTSENA) && | 277 | if ((flags & AR5K_TXDESC_RTSENA) && |
275 | (flags & AR5K_TXDESC_CTSENA)) | 278 | (flags & AR5K_TXDESC_CTSENA)) |
276 | return -EINVAL; | 279 | return -EINVAL; |
277 | tx_ctl->tx_control_2 |= rtscts_duration & | 280 | txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; |
278 | AR5K_4W_TX_DESC_CTL2_RTS_DURATION; | 281 | txctl3 |= AR5K_REG_SM(rtscts_rate, |
279 | tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, | ||
280 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); | 282 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); |
281 | } | 283 | } |
282 | 284 | ||
285 | tx_ctl->tx_control_0 = txctl0; | ||
286 | tx_ctl->tx_control_1 = txctl1; | ||
287 | tx_ctl->tx_control_2 = txctl2; | ||
288 | tx_ctl->tx_control_3 = txctl3; | ||
289 | |||
283 | return 0; | 290 | return 0; |
284 | } | 291 | } |
285 | 292 | ||
@@ -364,7 +371,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
364 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | 371 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); |
365 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | 372 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, |
366 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | 373 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); |
367 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | 374 | ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0, |
368 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | 375 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); |
369 | /*TODO: ts->ts_virtcol + test*/ | 376 | /*TODO: ts->ts_virtcol + test*/ |
370 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | 377 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, |
@@ -373,9 +380,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
373 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | 380 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); |
374 | ts->ts_antenna = 1; | 381 | ts->ts_antenna = 1; |
375 | ts->ts_status = 0; | 382 | ts->ts_status = 0; |
376 | ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0, | ||
377 | AR5K_2W_TX_DESC_CTL0_XMIT_RATE); | ||
378 | ts->ts_retry[0] = ts->ts_longretry; | ||
379 | ts->ts_final_idx = 0; | 383 | ts->ts_final_idx = 0; |
380 | 384 | ||
381 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | 385 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { |
@@ -401,81 +405,48 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, | |||
401 | { | 405 | { |
402 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | 406 | struct ath5k_hw_4w_tx_ctl *tx_ctl; |
403 | struct ath5k_hw_tx_status *tx_status; | 407 | struct ath5k_hw_tx_status *tx_status; |
408 | u32 txstat0, txstat1; | ||
404 | 409 | ||
405 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | 410 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; |
406 | tx_status = &desc->ud.ds_tx5212.tx_stat; | 411 | tx_status = &desc->ud.ds_tx5212.tx_stat; |
407 | 412 | ||
413 | txstat1 = ACCESS_ONCE(tx_status->tx_status_1); | ||
414 | |||
408 | /* No frame has been send or error */ | 415 | /* No frame has been send or error */ |
409 | if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) | 416 | if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE))) |
410 | return -EINPROGRESS; | 417 | return -EINPROGRESS; |
411 | 418 | ||
419 | txstat0 = ACCESS_ONCE(tx_status->tx_status_0); | ||
420 | |||
412 | /* | 421 | /* |
413 | * Get descriptor status | 422 | * Get descriptor status |
414 | */ | 423 | */ |
415 | ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, | 424 | ts->ts_tstamp = AR5K_REG_MS(txstat0, |
416 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | 425 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); |
417 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | 426 | ts->ts_shortretry = AR5K_REG_MS(txstat0, |
418 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | 427 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); |
419 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | 428 | ts->ts_final_retry = AR5K_REG_MS(txstat0, |
420 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | 429 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); |
421 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | 430 | ts->ts_seqnum = AR5K_REG_MS(txstat1, |
422 | AR5K_DESC_TX_STATUS1_SEQ_NUM); | 431 | AR5K_DESC_TX_STATUS1_SEQ_NUM); |
423 | ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, | 432 | ts->ts_rssi = AR5K_REG_MS(txstat1, |
424 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | 433 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); |
425 | ts->ts_antenna = (tx_status->tx_status_1 & | 434 | ts->ts_antenna = (txstat1 & |
426 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; | 435 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; |
427 | ts->ts_status = 0; | 436 | ts->ts_status = 0; |
428 | 437 | ||
429 | ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, | 438 | ts->ts_final_idx = AR5K_REG_MS(txstat1, |
430 | AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); | 439 | AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); |
431 | 440 | ||
432 | /* The longretry counter has the number of un-acked retries | ||
433 | * for the final rate. To get the total number of retries | ||
434 | * we have to add the retry counters for the other rates | ||
435 | * as well | ||
436 | */ | ||
437 | ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; | ||
438 | switch (ts->ts_final_idx) { | ||
439 | case 3: | ||
440 | ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
441 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); | ||
442 | |||
443 | ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
444 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); | ||
445 | ts->ts_longretry += ts->ts_retry[2]; | ||
446 | /* fall through */ | ||
447 | case 2: | ||
448 | ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
449 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); | ||
450 | |||
451 | ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
452 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
453 | ts->ts_longretry += ts->ts_retry[1]; | ||
454 | /* fall through */ | ||
455 | case 1: | ||
456 | ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
457 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); | ||
458 | |||
459 | ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
460 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
461 | ts->ts_longretry += ts->ts_retry[0]; | ||
462 | /* fall through */ | ||
463 | case 0: | ||
464 | ts->ts_rate[0] = tx_ctl->tx_control_3 & | ||
465 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
466 | break; | ||
467 | } | ||
468 | |||
469 | /* TX error */ | 441 | /* TX error */ |
470 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | 442 | if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { |
471 | if (tx_status->tx_status_0 & | 443 | if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) |
472 | AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) | ||
473 | ts->ts_status |= AR5K_TXERR_XRETRY; | 444 | ts->ts_status |= AR5K_TXERR_XRETRY; |
474 | 445 | ||
475 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) | 446 | if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) |
476 | ts->ts_status |= AR5K_TXERR_FIFO; | 447 | ts->ts_status |= AR5K_TXERR_FIFO; |
477 | 448 | ||
478 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) | 449 | if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED) |
479 | ts->ts_status |= AR5K_TXERR_FILT; | 450 | ts->ts_status |= AR5K_TXERR_FILT; |
480 | } | 451 | } |
481 | 452 | ||
@@ -609,37 +580,37 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
609 | struct ath5k_rx_status *rs) | 580 | struct ath5k_rx_status *rs) |
610 | { | 581 | { |
611 | struct ath5k_hw_rx_status *rx_status; | 582 | struct ath5k_hw_rx_status *rx_status; |
583 | u32 rxstat0, rxstat1; | ||
612 | 584 | ||
613 | rx_status = &desc->ud.ds_rx.rx_stat; | 585 | rx_status = &desc->ud.ds_rx.rx_stat; |
586 | rxstat1 = ACCESS_ONCE(rx_status->rx_status_1); | ||
614 | 587 | ||
615 | /* No frame received / not ready */ | 588 | /* No frame received / not ready */ |
616 | if (unlikely(!(rx_status->rx_status_1 & | 589 | if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE))) |
617 | AR5K_5212_RX_DESC_STATUS1_DONE))) | ||
618 | return -EINPROGRESS; | 590 | return -EINPROGRESS; |
619 | 591 | ||
620 | memset(rs, 0, sizeof(struct ath5k_rx_status)); | 592 | memset(rs, 0, sizeof(struct ath5k_rx_status)); |
593 | rxstat0 = ACCESS_ONCE(rx_status->rx_status_0); | ||
621 | 594 | ||
622 | /* | 595 | /* |
623 | * Frame receive status | 596 | * Frame receive status |
624 | */ | 597 | */ |
625 | rs->rs_datalen = rx_status->rx_status_0 & | 598 | rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN; |
626 | AR5K_5212_RX_DESC_STATUS0_DATA_LEN; | 599 | rs->rs_rssi = AR5K_REG_MS(rxstat0, |
627 | rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, | ||
628 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); | 600 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); |
629 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | 601 | rs->rs_rate = AR5K_REG_MS(rxstat0, |
630 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); | 602 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); |
631 | rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, | 603 | rs->rs_antenna = AR5K_REG_MS(rxstat0, |
632 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); | 604 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); |
633 | rs->rs_more = !!(rx_status->rx_status_0 & | 605 | rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE); |
634 | AR5K_5212_RX_DESC_STATUS0_MORE); | 606 | rs->rs_tstamp = AR5K_REG_MS(rxstat1, |
635 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | ||
636 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 607 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
637 | 608 | ||
638 | /* | 609 | /* |
639 | * Key table status | 610 | * Key table status |
640 | */ | 611 | */ |
641 | if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) | 612 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) |
642 | rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, | 613 | rs->rs_keyix = AR5K_REG_MS(rxstat1, |
643 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); | 614 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); |
644 | else | 615 | else |
645 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; | 616 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; |
@@ -647,27 +618,22 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
647 | /* | 618 | /* |
648 | * Receive/descriptor errors | 619 | * Receive/descriptor errors |
649 | */ | 620 | */ |
650 | if (!(rx_status->rx_status_1 & | 621 | if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { |
651 | AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { | 622 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) |
652 | if (rx_status->rx_status_1 & | ||
653 | AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) | ||
654 | rs->rs_status |= AR5K_RXERR_CRC; | 623 | rs->rs_status |= AR5K_RXERR_CRC; |
655 | 624 | ||
656 | if (rx_status->rx_status_1 & | 625 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { |
657 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { | ||
658 | rs->rs_status |= AR5K_RXERR_PHY; | 626 | rs->rs_status |= AR5K_RXERR_PHY; |
659 | rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, | 627 | rs->rs_phyerr = AR5K_REG_MS(rxstat1, |
660 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); | 628 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); |
661 | if (!ah->ah_capabilities.cap_has_phyerr_counters) | 629 | if (!ah->ah_capabilities.cap_has_phyerr_counters) |
662 | ath5k_ani_phy_error_report(ah, rs->rs_phyerr); | 630 | ath5k_ani_phy_error_report(ah, rs->rs_phyerr); |
663 | } | 631 | } |
664 | 632 | ||
665 | if (rx_status->rx_status_1 & | 633 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) |
666 | AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) | ||
667 | rs->rs_status |= AR5K_RXERR_DECRYPT; | 634 | rs->rs_status |= AR5K_RXERR_DECRYPT; |
668 | 635 | ||
669 | if (rx_status->rx_status_1 & | 636 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) |
670 | AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) | ||
671 | rs->rs_status |= AR5K_RXERR_MIC; | 637 | rs->rs_status |= AR5K_RXERR_MIC; |
672 | } | 638 | } |
673 | return 0; | 639 | return 0; |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index b6561f785c6e..e9263e4c7f3e 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -660,6 +660,53 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) | |||
660 | vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; | 660 | vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; |
661 | } | 661 | } |
662 | 662 | ||
663 | static int | ||
664 | ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) | ||
665 | { | ||
666 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
667 | struct ath5k_chan_pcal_info *chinfo; | ||
668 | u8 pier, pdg; | ||
669 | |||
670 | switch (mode) { | ||
671 | case AR5K_EEPROM_MODE_11A: | ||
672 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) | ||
673 | return 0; | ||
674 | chinfo = ee->ee_pwr_cal_a; | ||
675 | break; | ||
676 | case AR5K_EEPROM_MODE_11B: | ||
677 | if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) | ||
678 | return 0; | ||
679 | chinfo = ee->ee_pwr_cal_b; | ||
680 | break; | ||
681 | case AR5K_EEPROM_MODE_11G: | ||
682 | if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) | ||
683 | return 0; | ||
684 | chinfo = ee->ee_pwr_cal_g; | ||
685 | break; | ||
686 | default: | ||
687 | return -EINVAL; | ||
688 | } | ||
689 | |||
690 | for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { | ||
691 | if (!chinfo[pier].pd_curves) | ||
692 | continue; | ||
693 | |||
694 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | ||
695 | struct ath5k_pdgain_info *pd = | ||
696 | &chinfo[pier].pd_curves[pdg]; | ||
697 | |||
698 | if (pd != NULL) { | ||
699 | kfree(pd->pd_step); | ||
700 | kfree(pd->pd_pwr); | ||
701 | } | ||
702 | } | ||
703 | |||
704 | kfree(chinfo[pier].pd_curves); | ||
705 | } | ||
706 | |||
707 | return 0; | ||
708 | } | ||
709 | |||
663 | /* Convert RF5111 specific data to generic raw data | 710 | /* Convert RF5111 specific data to generic raw data |
664 | * used by interpolation code */ | 711 | * used by interpolation code */ |
665 | static int | 712 | static int |
@@ -684,7 +731,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
684 | GFP_KERNEL); | 731 | GFP_KERNEL); |
685 | 732 | ||
686 | if (!chinfo[pier].pd_curves) | 733 | if (!chinfo[pier].pd_curves) |
687 | return -ENOMEM; | 734 | goto err_out; |
688 | 735 | ||
689 | /* Only one curve for RF5111 | 736 | /* Only one curve for RF5111 |
690 | * find out which one and place | 737 | * find out which one and place |
@@ -708,12 +755,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
708 | pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, | 755 | pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, |
709 | sizeof(u8), GFP_KERNEL); | 756 | sizeof(u8), GFP_KERNEL); |
710 | if (!pd->pd_step) | 757 | if (!pd->pd_step) |
711 | return -ENOMEM; | 758 | goto err_out; |
712 | 759 | ||
713 | pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, | 760 | pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, |
714 | sizeof(s16), GFP_KERNEL); | 761 | sizeof(s16), GFP_KERNEL); |
715 | if (!pd->pd_pwr) | 762 | if (!pd->pd_pwr) |
716 | return -ENOMEM; | 763 | goto err_out; |
717 | 764 | ||
718 | /* Fill raw dataset | 765 | /* Fill raw dataset |
719 | * (convert power to 0.25dB units | 766 | * (convert power to 0.25dB units |
@@ -734,6 +781,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
734 | } | 781 | } |
735 | 782 | ||
736 | return 0; | 783 | return 0; |
784 | |||
785 | err_out: | ||
786 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
787 | return -ENOMEM; | ||
737 | } | 788 | } |
738 | 789 | ||
739 | /* Parse EEPROM data */ | 790 | /* Parse EEPROM data */ |
@@ -867,7 +918,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
867 | GFP_KERNEL); | 918 | GFP_KERNEL); |
868 | 919 | ||
869 | if (!chinfo[pier].pd_curves) | 920 | if (!chinfo[pier].pd_curves) |
870 | return -ENOMEM; | 921 | goto err_out; |
871 | 922 | ||
872 | /* Fill pd_curves */ | 923 | /* Fill pd_curves */ |
873 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | 924 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { |
@@ -886,14 +937,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
886 | sizeof(u8), GFP_KERNEL); | 937 | sizeof(u8), GFP_KERNEL); |
887 | 938 | ||
888 | if (!pd->pd_step) | 939 | if (!pd->pd_step) |
889 | return -ENOMEM; | 940 | goto err_out; |
890 | 941 | ||
891 | pd->pd_pwr = kcalloc(pd->pd_points, | 942 | pd->pd_pwr = kcalloc(pd->pd_points, |
892 | sizeof(s16), GFP_KERNEL); | 943 | sizeof(s16), GFP_KERNEL); |
893 | 944 | ||
894 | if (!pd->pd_pwr) | 945 | if (!pd->pd_pwr) |
895 | return -ENOMEM; | 946 | goto err_out; |
896 | |||
897 | 947 | ||
898 | /* Fill raw dataset | 948 | /* Fill raw dataset |
899 | * (all power levels are in 0.25dB units) */ | 949 | * (all power levels are in 0.25dB units) */ |
@@ -925,13 +975,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
925 | sizeof(u8), GFP_KERNEL); | 975 | sizeof(u8), GFP_KERNEL); |
926 | 976 | ||
927 | if (!pd->pd_step) | 977 | if (!pd->pd_step) |
928 | return -ENOMEM; | 978 | goto err_out; |
929 | 979 | ||
930 | pd->pd_pwr = kcalloc(pd->pd_points, | 980 | pd->pd_pwr = kcalloc(pd->pd_points, |
931 | sizeof(s16), GFP_KERNEL); | 981 | sizeof(s16), GFP_KERNEL); |
932 | 982 | ||
933 | if (!pd->pd_pwr) | 983 | if (!pd->pd_pwr) |
934 | return -ENOMEM; | 984 | goto err_out; |
935 | 985 | ||
936 | /* Fill raw dataset | 986 | /* Fill raw dataset |
937 | * (all power levels are in 0.25dB units) */ | 987 | * (all power levels are in 0.25dB units) */ |
@@ -954,6 +1004,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
954 | } | 1004 | } |
955 | 1005 | ||
956 | return 0; | 1006 | return 0; |
1007 | |||
1008 | err_out: | ||
1009 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
1010 | return -ENOMEM; | ||
957 | } | 1011 | } |
958 | 1012 | ||
959 | /* Parse EEPROM data */ | 1013 | /* Parse EEPROM data */ |
@@ -1156,7 +1210,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1156 | GFP_KERNEL); | 1210 | GFP_KERNEL); |
1157 | 1211 | ||
1158 | if (!chinfo[pier].pd_curves) | 1212 | if (!chinfo[pier].pd_curves) |
1159 | return -ENOMEM; | 1213 | goto err_out; |
1160 | 1214 | ||
1161 | /* Fill pd_curves */ | 1215 | /* Fill pd_curves */ |
1162 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | 1216 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { |
@@ -1177,13 +1231,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1177 | sizeof(u8), GFP_KERNEL); | 1231 | sizeof(u8), GFP_KERNEL); |
1178 | 1232 | ||
1179 | if (!pd->pd_step) | 1233 | if (!pd->pd_step) |
1180 | return -ENOMEM; | 1234 | goto err_out; |
1181 | 1235 | ||
1182 | pd->pd_pwr = kcalloc(pd->pd_points, | 1236 | pd->pd_pwr = kcalloc(pd->pd_points, |
1183 | sizeof(s16), GFP_KERNEL); | 1237 | sizeof(s16), GFP_KERNEL); |
1184 | 1238 | ||
1185 | if (!pd->pd_pwr) | 1239 | if (!pd->pd_pwr) |
1186 | return -ENOMEM; | 1240 | goto err_out; |
1187 | 1241 | ||
1188 | /* Fill raw dataset | 1242 | /* Fill raw dataset |
1189 | * convert all pwr levels to | 1243 | * convert all pwr levels to |
@@ -1213,6 +1267,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1213 | } | 1267 | } |
1214 | 1268 | ||
1215 | return 0; | 1269 | return 0; |
1270 | |||
1271 | err_out: | ||
1272 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
1273 | return -ENOMEM; | ||
1216 | } | 1274 | } |
1217 | 1275 | ||
1218 | /* Parse EEPROM data */ | 1276 | /* Parse EEPROM data */ |
@@ -1534,53 +1592,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) | |||
1534 | return 0; | 1592 | return 0; |
1535 | } | 1593 | } |
1536 | 1594 | ||
1537 | static int | ||
1538 | ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) | ||
1539 | { | ||
1540 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
1541 | struct ath5k_chan_pcal_info *chinfo; | ||
1542 | u8 pier, pdg; | ||
1543 | |||
1544 | switch (mode) { | ||
1545 | case AR5K_EEPROM_MODE_11A: | ||
1546 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) | ||
1547 | return 0; | ||
1548 | chinfo = ee->ee_pwr_cal_a; | ||
1549 | break; | ||
1550 | case AR5K_EEPROM_MODE_11B: | ||
1551 | if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) | ||
1552 | return 0; | ||
1553 | chinfo = ee->ee_pwr_cal_b; | ||
1554 | break; | ||
1555 | case AR5K_EEPROM_MODE_11G: | ||
1556 | if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) | ||
1557 | return 0; | ||
1558 | chinfo = ee->ee_pwr_cal_g; | ||
1559 | break; | ||
1560 | default: | ||
1561 | return -EINVAL; | ||
1562 | } | ||
1563 | |||
1564 | for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { | ||
1565 | if (!chinfo[pier].pd_curves) | ||
1566 | continue; | ||
1567 | |||
1568 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | ||
1569 | struct ath5k_pdgain_info *pd = | ||
1570 | &chinfo[pier].pd_curves[pdg]; | ||
1571 | |||
1572 | if (pd != NULL) { | ||
1573 | kfree(pd->pd_step); | ||
1574 | kfree(pd->pd_pwr); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | kfree(chinfo[pier].pd_curves); | ||
1579 | } | ||
1580 | |||
1581 | return 0; | ||
1582 | } | ||
1583 | |||
1584 | /* Read conformance test limits used for regulatory control */ | 1595 | /* Read conformance test limits used for regulatory control */ |
1585 | static int | 1596 | static int |
1586 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) | 1597 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) |
@@ -1721,35 +1732,6 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) | |||
1721 | return ret; | 1732 | return ret; |
1722 | } | 1733 | } |
1723 | 1734 | ||
1724 | /* | ||
1725 | * Read the MAC address from eeprom | ||
1726 | */ | ||
1727 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
1728 | { | ||
1729 | u8 mac_d[ETH_ALEN] = {}; | ||
1730 | u32 total, offset; | ||
1731 | u16 data; | ||
1732 | int octet; | ||
1733 | |||
1734 | AR5K_EEPROM_READ(0x20, data); | ||
1735 | |||
1736 | for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { | ||
1737 | AR5K_EEPROM_READ(offset, data); | ||
1738 | |||
1739 | total += data; | ||
1740 | mac_d[octet + 1] = data & 0xff; | ||
1741 | mac_d[octet] = data >> 8; | ||
1742 | octet += 2; | ||
1743 | } | ||
1744 | |||
1745 | if (!total || total == 3 * 0xffff) | ||
1746 | return -EINVAL; | ||
1747 | |||
1748 | memcpy(mac, mac_d, ETH_ALEN); | ||
1749 | |||
1750 | return 0; | ||
1751 | } | ||
1752 | |||
1753 | 1735 | ||
1754 | /***********************\ | 1736 | /***********************\ |
1755 | * Init/Detach functions * | 1737 | * Init/Detach functions * |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 9be29b728b1c..807bd6440169 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -282,6 +282,15 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
282 | if (changes & BSS_CHANGED_BEACON_INT) | 282 | if (changes & BSS_CHANGED_BEACON_INT) |
283 | sc->bintval = bss_conf->beacon_int; | 283 | sc->bintval = bss_conf->beacon_int; |
284 | 284 | ||
285 | if (changes & BSS_CHANGED_ERP_SLOT) { | ||
286 | int slot_time; | ||
287 | |||
288 | ah->ah_short_slot = bss_conf->use_short_slot; | ||
289 | slot_time = ath5k_hw_get_default_slottime(ah) + | ||
290 | 3 * ah->ah_coverage_class; | ||
291 | ath5k_hw_set_ifs_intervals(ah, slot_time); | ||
292 | } | ||
293 | |||
285 | if (changes & BSS_CHANGED_ASSOC) { | 294 | if (changes & BSS_CHANGED_ASSOC) { |
286 | avf->assoc = bss_conf->assoc; | 295 | avf->assoc = bss_conf->assoc; |
287 | if (bss_conf->assoc) | 296 | if (bss_conf->assoc) |
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 66598a0d1df0..5cc4a2fe47b6 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/pci-aspm.h> | 19 | #include <linux/pci-aspm.h> |
20 | #include <linux/etherdevice.h> | ||
20 | #include "../ath.h" | 21 | #include "../ath.h" |
21 | #include "ath5k.h" | 22 | #include "ath5k.h" |
22 | #include "debug.h" | 23 | #include "debug.h" |
@@ -108,11 +109,42 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) | |||
108 | return 0; | 109 | return 0; |
109 | } | 110 | } |
110 | 111 | ||
112 | /* | ||
113 | * Read the MAC address from eeprom or platform_data | ||
114 | */ | ||
115 | static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
116 | { | ||
117 | u8 mac_d[ETH_ALEN] = {}; | ||
118 | u32 total, offset; | ||
119 | u16 data; | ||
120 | int octet; | ||
121 | |||
122 | AR5K_EEPROM_READ(0x20, data); | ||
123 | |||
124 | for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { | ||
125 | AR5K_EEPROM_READ(offset, data); | ||
126 | |||
127 | total += data; | ||
128 | mac_d[octet + 1] = data & 0xff; | ||
129 | mac_d[octet] = data >> 8; | ||
130 | octet += 2; | ||
131 | } | ||
132 | |||
133 | if (!total || total == 3 * 0xffff) | ||
134 | return -EINVAL; | ||
135 | |||
136 | memcpy(mac, mac_d, ETH_ALEN); | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | |||
111 | /* Common ath_bus_opts structure */ | 142 | /* Common ath_bus_opts structure */ |
112 | static const struct ath_bus_ops ath_pci_bus_ops = { | 143 | static const struct ath_bus_ops ath_pci_bus_ops = { |
113 | .ath_bus_type = ATH_PCI, | 144 | .ath_bus_type = ATH_PCI, |
114 | .read_cachesize = ath5k_pci_read_cachesize, | 145 | .read_cachesize = ath5k_pci_read_cachesize, |
115 | .eeprom_read = ath5k_pci_eeprom_read, | 146 | .eeprom_read = ath5k_pci_eeprom_read, |
147 | .eeprom_read_mac = ath5k_pci_eeprom_read_mac, | ||
116 | }; | 148 | }; |
117 | 149 | ||
118 | /********************\ | 150 | /********************\ |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index a702817daf72..71b60b7c617e 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -75,7 +75,7 @@ static const unsigned int ack_rates_high[] = | |||
75 | * bwmodes. | 75 | * bwmodes. |
76 | */ | 76 | */ |
77 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | 77 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, |
78 | int len, struct ieee80211_rate *rate) | 78 | int len, struct ieee80211_rate *rate, bool shortpre) |
79 | { | 79 | { |
80 | struct ath5k_softc *sc = ah->ah_sc; | 80 | struct ath5k_softc *sc = ah->ah_sc; |
81 | int sifs, preamble, plcp_bits, sym_time; | 81 | int sifs, preamble, plcp_bits, sym_time; |
@@ -84,9 +84,15 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | |||
84 | 84 | ||
85 | /* Fallback */ | 85 | /* Fallback */ |
86 | if (!ah->ah_bwmode) { | 86 | if (!ah->ah_bwmode) { |
87 | dur = ieee80211_generic_frame_duration(sc->hw, | 87 | __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw, |
88 | NULL, len, rate); | 88 | NULL, len, rate); |
89 | return le16_to_cpu(dur); | 89 | |
90 | /* subtract difference between long and short preamble */ | ||
91 | dur = le16_to_cpu(raw_dur); | ||
92 | if (shortpre) | ||
93 | dur -= 96; | ||
94 | |||
95 | return dur; | ||
90 | } | 96 | } |
91 | 97 | ||
92 | bitrate = rate->bitrate; | 98 | bitrate = rate->bitrate; |
@@ -145,9 +151,9 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) | |||
145 | slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; | 151 | slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; |
146 | break; | 152 | break; |
147 | case AR5K_BWMODE_DEFAULT: | 153 | case AR5K_BWMODE_DEFAULT: |
148 | slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; | ||
149 | default: | 154 | default: |
150 | if (channel->hw_value & CHANNEL_CCK) | 155 | slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; |
156 | if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot) | ||
151 | slot_time = AR5K_INIT_SLOT_TIME_B; | 157 | slot_time = AR5K_INIT_SLOT_TIME_B; |
152 | break; | 158 | break; |
153 | } | 159 | } |
@@ -263,27 +269,14 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah) | |||
263 | * actual rate for this rate. See mac80211 tx.c | 269 | * actual rate for this rate. See mac80211 tx.c |
264 | * ieee80211_duration() for a brief description of | 270 | * ieee80211_duration() for a brief description of |
265 | * what rate we should choose to TX ACKs. */ | 271 | * what rate we should choose to TX ACKs. */ |
266 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); | 272 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); |
267 | 273 | ||
268 | ath5k_hw_reg_write(ah, tx_time, reg); | 274 | ath5k_hw_reg_write(ah, tx_time, reg); |
269 | 275 | ||
270 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) | 276 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) |
271 | continue; | 277 | continue; |
272 | 278 | ||
273 | /* | 279 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true); |
274 | * We're not distinguishing short preamble here, | ||
275 | * This is true, all we'll get is a longer value here | ||
276 | * which is not necessarilly bad. We could use | ||
277 | * export ieee80211_frame_duration() but that needs to be | ||
278 | * fixed first to be properly used by mac802111 drivers: | ||
279 | * | ||
280 | * - remove erp stuff and let the routine figure ofdm | ||
281 | * erp rates | ||
282 | * - remove passing argument ieee80211_local as | ||
283 | * drivers don't have access to it | ||
284 | * - move drivers using ieee80211_generic_frame_duration() | ||
285 | * to this | ||
286 | */ | ||
287 | ath5k_hw_reg_write(ah, tx_time, | 280 | ath5k_hw_reg_write(ah, tx_time, |
288 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); | 281 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); |
289 | } | 282 | } |
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 3343fb9e4940..b18c5021aac3 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -519,7 +519,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) | |||
519 | return -EINVAL; | 519 | return -EINVAL; |
520 | 520 | ||
521 | sifs = ath5k_hw_get_default_sifs(ah); | 521 | sifs = ath5k_hw_get_default_sifs(ah); |
522 | sifs_clock = ath5k_hw_htoclock(ah, sifs); | 522 | sifs_clock = ath5k_hw_htoclock(ah, sifs - 2); |
523 | 523 | ||
524 | /* EIFS | 524 | /* EIFS |
525 | * Txtime of ack at lowest rate + SIFS + DIFS | 525 | * Txtime of ack at lowest rate + SIFS + DIFS |
@@ -550,7 +550,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) | |||
550 | else | 550 | else |
551 | rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; | 551 | rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; |
552 | 552 | ||
553 | ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); | 553 | ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); |
554 | 554 | ||
555 | /* ack_tx_time includes an SIFS already */ | 555 | /* ack_tx_time includes an SIFS already */ |
556 | eifs = ack_tx_time + sifs + 2 * slot_time; | 556 | eifs = ack_tx_time + sifs + 2 * slot_time; |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index ad57a6d23110..d9ff8413ab9a 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -5,7 +5,7 @@ config ATH9K_COMMON | |||
5 | 5 | ||
6 | config ATH9K | 6 | config ATH9K |
7 | tristate "Atheros 802.11n wireless cards support" | 7 | tristate "Atheros 802.11n wireless cards support" |
8 | depends on PCI && MAC80211 | 8 | depends on MAC80211 |
9 | select ATH9K_HW | 9 | select ATH9K_HW |
10 | select MAC80211_LEDS | 10 | select MAC80211_LEDS |
11 | select LEDS_CLASS | 11 | select LEDS_CLASS |
@@ -23,6 +23,25 @@ config ATH9K | |||
23 | 23 | ||
24 | If you choose to build a module, it'll be called ath9k. | 24 | If you choose to build a module, it'll be called ath9k. |
25 | 25 | ||
26 | config ATH9K_PCI | ||
27 | bool "Atheros ath9k PCI/PCIe bus support" | ||
28 | depends on ATH9K && PCI | ||
29 | default PCI | ||
30 | ---help--- | ||
31 | This option enables the PCI bus support in ath9k. | ||
32 | |||
33 | Say Y, if you have a compatible PCI/PCIe wireless card. | ||
34 | |||
35 | config ATH9K_AHB | ||
36 | bool "Atheros ath9k AHB bus support" | ||
37 | depends on ATH9K | ||
38 | default n | ||
39 | ---help--- | ||
40 | This option enables the AHB bus support in ath9k. | ||
41 | |||
42 | Say Y, if you have a SoC with a compatible built-in | ||
43 | wireless MAC. Say N if unsure. | ||
44 | |||
26 | config ATH9K_DEBUGFS | 45 | config ATH9K_DEBUGFS |
27 | bool "Atheros ath9k debugging" | 46 | bool "Atheros ath9k debugging" |
28 | depends on ATH9K && DEBUG_FS | 47 | depends on ATH9K && DEBUG_FS |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4d66ca8042eb..05a6fade7b1c 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -6,8 +6,8 @@ ath9k-y += beacon.o \ | |||
6 | xmit.o \ | 6 | xmit.o \ |
7 | 7 | ||
8 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o | 8 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o |
9 | ath9k-$(CONFIG_PCI) += pci.o | 9 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o |
10 | ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o | 10 | ath9k-$(CONFIG_ATH9K_AHB) += ahb.o |
11 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o | 11 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o |
12 | 12 | ||
13 | obj-$(CONFIG_ATH9K) += ath9k.o | 13 | obj-$(CONFIG_ATH9K) += ath9k.o |
@@ -48,4 +48,6 @@ ath9k_htc-y += htc_hst.o \ | |||
48 | htc_drv_init.o \ | 48 | htc_drv_init.o \ |
49 | htc_drv_gpio.o | 49 | htc_drv_gpio.o |
50 | 50 | ||
51 | ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o | ||
52 | |||
51 | obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o | 53 | obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 9cb0efa9b4c0..5193ed58a17b 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -21,6 +21,14 @@ | |||
21 | #include <linux/ath9k_platform.h> | 21 | #include <linux/ath9k_platform.h> |
22 | #include "ath9k.h" | 22 | #include "ath9k.h" |
23 | 23 | ||
24 | const struct platform_device_id ath9k_platform_id_table[] = { | ||
25 | { | ||
26 | .name = "ath9k", | ||
27 | .driver_data = AR5416_AR9100_DEVID, | ||
28 | }, | ||
29 | {}, | ||
30 | }; | ||
31 | |||
24 | /* return bus cachesize in 4B word units */ | 32 | /* return bus cachesize in 4B word units */ |
25 | static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) | 33 | static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) |
26 | { | 34 | { |
@@ -57,6 +65,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
57 | struct ath_softc *sc; | 65 | struct ath_softc *sc; |
58 | struct ieee80211_hw *hw; | 66 | struct ieee80211_hw *hw; |
59 | struct resource *res; | 67 | struct resource *res; |
68 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
60 | int irq; | 69 | int irq; |
61 | int ret = 0; | 70 | int ret = 0; |
62 | struct ath_hw *ah; | 71 | struct ath_hw *ah; |
@@ -116,7 +125,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
116 | goto err_free_hw; | 125 | goto err_free_hw; |
117 | } | 126 | } |
118 | 127 | ||
119 | ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); | 128 | ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops); |
120 | if (ret) { | 129 | if (ret) { |
121 | dev_err(&pdev->dev, "failed to initialize device\n"); | 130 | dev_err(&pdev->dev, "failed to initialize device\n"); |
122 | goto err_irq; | 131 | goto err_irq; |
@@ -165,8 +174,11 @@ static struct platform_driver ath_ahb_driver = { | |||
165 | .name = "ath9k", | 174 | .name = "ath9k", |
166 | .owner = THIS_MODULE, | 175 | .owner = THIS_MODULE, |
167 | }, | 176 | }, |
177 | .id_table = ath9k_platform_id_table, | ||
168 | }; | 178 | }; |
169 | 179 | ||
180 | MODULE_DEVICE_TABLE(platform, ath9k_platform_id_table); | ||
181 | |||
170 | int ath_ahb_init(void) | 182 | int ath_ahb_init(void) |
171 | { | 183 | { |
172 | return platform_driver_register(&ath_ahb_driver); | 184 | return platform_driver_register(&ath_ahb_driver); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 37663dbbcf57..47780ef1c892 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h | |||
@@ -483,7 +483,11 @@ | |||
483 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 | 483 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 |
484 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 | 484 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 |
485 | 485 | ||
486 | #define AR_PHY_TX_PWRCTRL8 0xa278 | ||
487 | |||
486 | #define AR_PHY_TX_PWRCTRL9 0xa27C | 488 | #define AR_PHY_TX_PWRCTRL9 0xa27C |
489 | |||
490 | #define AR_PHY_TX_PWRCTRL10 0xa394 | ||
487 | #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 | 491 | #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 |
488 | #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 | 492 | #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 |
489 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 | 493 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 |
@@ -495,6 +499,8 @@ | |||
495 | 499 | ||
496 | #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 | 500 | #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 |
497 | #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 | 501 | #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 |
502 | #define AR_PHY_CH0_TX_PWRCTRL12 0xa3dc | ||
503 | #define AR_PHY_CH0_TX_PWRCTRL13 0xa3e0 | ||
498 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 | 504 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 |
499 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 | 505 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 |
500 | 506 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 9ecca93392e8..f915a3dbfcad 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | |||
@@ -34,10 +34,10 @@ static const u32 ar9300_2p2_radio_postamble[][5] = { | |||
34 | 34 | ||
35 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { | 35 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { |
36 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 36 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
37 | {0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, | 37 | {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
38 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, | 38 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
39 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, | 39 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
40 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 40 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
41 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | 41 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
42 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 42 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
43 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | 43 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, |
@@ -119,14 +119,14 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { | |||
119 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | 119 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
120 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | 120 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
121 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | 121 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
122 | {0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, | 122 | {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
123 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, | 123 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
124 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, | 124 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
125 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 125 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
126 | {0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, | 126 | {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
127 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, | 127 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
128 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, | 128 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
129 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 129 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
130 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | 130 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, |
131 | {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, | 131 | {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, |
132 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 132 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
@@ -835,10 +835,10 @@ static const u32 ar9300_2p2_baseband_core[][2] = { | |||
835 | 835 | ||
836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | 836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { |
837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
838 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 838 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, |
839 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 839 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, |
840 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 840 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, |
841 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 841 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
842 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | 842 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, |
843 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | 843 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, |
844 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | 844 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, |
@@ -920,14 +920,14 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | |||
920 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 920 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
921 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 921 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
922 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 922 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
923 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 923 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, |
924 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 924 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, |
925 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 925 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, |
926 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 926 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
927 | {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 927 | {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, |
928 | {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 928 | {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, |
929 | {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 929 | {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, |
930 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 930 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
931 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | 931 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, |
932 | {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, | 932 | {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, |
933 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | 933 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, |
@@ -941,10 +941,10 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | |||
941 | 941 | ||
942 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { | 942 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { |
943 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 943 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
944 | {0x0000a2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, | 944 | {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, |
945 | {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, | 945 | {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, |
946 | {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, | 946 | {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, |
947 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 947 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
948 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | 948 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, |
949 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | 949 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, |
950 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | 950 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, |
@@ -1026,14 +1026,14 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { | |||
1026 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 1026 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
1027 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 1027 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
1028 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 1028 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
1029 | {0x0000b2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, | 1029 | {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, |
1030 | {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, | 1030 | {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, |
1031 | {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, | 1031 | {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, |
1032 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1032 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1033 | {0x0000c2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, | 1033 | {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, |
1034 | {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, | 1034 | {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, |
1035 | {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, | 1035 | {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, |
1036 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1036 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1037 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | 1037 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, |
1038 | {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, | 1038 | {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, |
1039 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 1039 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
@@ -1307,10 +1307,10 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { | |||
1307 | 1307 | ||
1308 | static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { | 1308 | static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { |
1309 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 1309 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
1310 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 1310 | {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
1311 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 1311 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
1312 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 1312 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
1313 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1313 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1314 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | 1314 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
1315 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1315 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1316 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | 1316 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, |
@@ -1329,21 +1329,21 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { | |||
1329 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | 1329 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, |
1330 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | 1330 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, |
1331 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | 1331 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, |
1332 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | 1332 | {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, |
1333 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | 1333 | {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, |
1334 | {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, | 1334 | {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, |
1335 | {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, | 1335 | {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, |
1336 | {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, | 1336 | {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, |
1337 | {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, | 1337 | {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, |
1338 | {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, | 1338 | {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, |
1339 | {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, | 1339 | {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, |
1340 | {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1340 | {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1341 | {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1341 | {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1342 | {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1342 | {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1343 | {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1343 | {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1344 | {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1344 | {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1345 | {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1345 | {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1346 | {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1346 | {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1347 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | 1347 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, |
1348 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | 1348 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, |
1349 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | 1349 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, |
@@ -1361,45 +1361,45 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { | |||
1361 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, | 1361 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, |
1362 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, | 1362 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, |
1363 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, | 1363 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, |
1364 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, | 1364 | {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, |
1365 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, | 1365 | {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, |
1366 | {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, | 1366 | {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, |
1367 | {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, | 1367 | {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, |
1368 | {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, | 1368 | {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, |
1369 | {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, | 1369 | {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, |
1370 | {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, | 1370 | {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, |
1371 | {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, | 1371 | {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, |
1372 | {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1372 | {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1373 | {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1373 | {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1374 | {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1374 | {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1375 | {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1375 | {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1376 | {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1376 | {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1377 | {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1377 | {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1378 | {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1378 | {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1379 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1379 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1380 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1380 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1381 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1381 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1382 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1382 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1383 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1383 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1384 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | 1384 | {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, |
1385 | {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, | 1385 | {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, |
1386 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, | 1386 | {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, |
1387 | {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, | 1387 | {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, |
1388 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, | 1388 | {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, |
1389 | {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, | 1389 | {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, |
1390 | {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, | 1390 | {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1391 | {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1391 | {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1392 | {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1392 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1393 | {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1393 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1394 | {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1394 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1395 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 1395 | {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
1396 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 1396 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
1397 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 1397 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
1398 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1398 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1399 | {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 1399 | {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
1400 | {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 1400 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
1401 | {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 1401 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
1402 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1402 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1403 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | 1403 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, |
1404 | {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, | 1404 | {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, |
1405 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 1405 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index eb250d6b8038..1bc33f51e466 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -75,9 +75,18 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
75 | freq = centers.synth_center; | 75 | freq = centers.synth_center; |
76 | 76 | ||
77 | if (freq < 4800) { /* 2 GHz, fractional mode */ | 77 | if (freq < 4800) { /* 2 GHz, fractional mode */ |
78 | if (AR_SREV_9485(ah)) | 78 | if (AR_SREV_9485(ah)) { |
79 | channelSel = CHANSEL_2G_9485(freq); | 79 | u32 chan_frac; |
80 | else | 80 | |
81 | /* | ||
82 | * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0 | ||
83 | * ndiv = ((chan_mhz * 4) / 3) / freq_ref; | ||
84 | * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 | ||
85 | */ | ||
86 | channelSel = (freq * 4) / 120; | ||
87 | chan_frac = (((freq * 4) % 120) * 0x20000) / 120; | ||
88 | channelSel = (channelSel << 17) | chan_frac; | ||
89 | } else | ||
81 | channelSel = CHANSEL_2G(freq); | 90 | channelSel = CHANSEL_2G(freq); |
82 | /* Set to 2G mode */ | 91 | /* Set to 2G mode */ |
83 | bMode = 1; | 92 | bMode = 1; |
@@ -401,7 +410,7 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, | |||
401 | 410 | ||
402 | ar9003_hw_spur_ofdm_clear(ah); | 411 | ar9003_hw_spur_ofdm_clear(ah); |
403 | 412 | ||
404 | for (i = 0; spurChansPtr[i] && i < 5; i++) { | 413 | for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) { |
405 | freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; | 414 | freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; |
406 | if (abs(freq_offset) < range) { | 415 | if (abs(freq_offset) < range) { |
407 | ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); | 416 | ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index f91f73e50d00..fbdde29f0ab8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h | |||
@@ -396,7 +396,7 @@ static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { | |||
396 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 396 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
397 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 397 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
398 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 398 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
399 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 399 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
400 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 400 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
401 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 401 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
402 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 402 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -469,7 +469,7 @@ static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { | |||
469 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 469 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
470 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 470 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
471 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 471 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
472 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 472 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
473 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 473 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
474 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 474 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
475 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 475 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -635,7 +635,7 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { | |||
635 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 635 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
636 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 636 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
637 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 637 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
638 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 638 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
639 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 639 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
640 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 640 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
641 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 641 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -728,7 +728,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { | |||
728 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 728 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
729 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 729 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
730 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 730 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
731 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 731 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
732 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 732 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
733 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 733 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
734 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 734 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -827,7 +827,7 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { | |||
827 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 827 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
828 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 828 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
829 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 829 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
830 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 830 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
831 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 831 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
832 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 832 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
833 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 833 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 38835bc324b2..77ad407e9fa3 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -665,7 +665,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); | |||
665 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); | 665 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); |
666 | bool ath9k_uses_beacons(int type); | 666 | bool ath9k_uses_beacons(int type); |
667 | 667 | ||
668 | #ifdef CONFIG_PCI | 668 | #ifdef CONFIG_ATH9K_PCI |
669 | int ath_pci_init(void); | 669 | int ath_pci_init(void); |
670 | void ath_pci_exit(void); | 670 | void ath_pci_exit(void); |
671 | #else | 671 | #else |
@@ -673,7 +673,7 @@ static inline int ath_pci_init(void) { return 0; }; | |||
673 | static inline void ath_pci_exit(void) {}; | 673 | static inline void ath_pci_exit(void) {}; |
674 | #endif | 674 | #endif |
675 | 675 | ||
676 | #ifdef CONFIG_ATHEROS_AR71XX | 676 | #ifdef CONFIG_ATH9K_AHB |
677 | int ath_ahb_init(void); | 677 | int ath_ahb_init(void); |
678 | void ath_ahb_exit(void); | 678 | void ath_ahb_exit(void); |
679 | #else | 679 | #else |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index eccb0ec87adb..9193a385ceb2 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -320,6 +320,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) | |||
320 | if (avp->av_bcbuf != NULL) { | 320 | if (avp->av_bcbuf != NULL) { |
321 | struct ath_buf *bf; | 321 | struct ath_buf *bf; |
322 | 322 | ||
323 | avp->is_bslot_active = false; | ||
323 | if (avp->av_bslot != -1) { | 324 | if (avp->av_bslot != -1) { |
324 | sc->beacon.bslot[avp->av_bslot] = NULL; | 325 | sc->beacon.bslot[avp->av_bslot] = NULL; |
325 | sc->nbcnvifs--; | 326 | sc->nbcnvifs--; |
@@ -743,7 +744,6 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
743 | cur_conf->dtim_period = 1; | 744 | cur_conf->dtim_period = 1; |
744 | 745 | ||
745 | ath_set_beacon(sc); | 746 | ath_set_beacon(sc); |
746 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
747 | } | 747 | } |
748 | 748 | ||
749 | void ath_set_beacon(struct ath_softc *sc) | 749 | void ath_set_beacon(struct ath_softc *sc) |
@@ -761,6 +761,12 @@ void ath_set_beacon(struct ath_softc *sc) | |||
761 | break; | 761 | break; |
762 | case NL80211_IFTYPE_STATION: | 762 | case NL80211_IFTYPE_STATION: |
763 | ath_beacon_config_sta(sc, cur_conf); | 763 | ath_beacon_config_sta(sc, cur_conf); |
764 | /* | ||
765 | * Request a re-configuration of Beacon related timers | ||
766 | * on the receipt of the first Beacon frame (i.e., | ||
767 | * after time sync with the AP). | ||
768 | */ | ||
769 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
764 | break; | 770 | break; |
765 | default: | 771 | default: |
766 | ath_dbg(common, ATH_DBG_CONFIG, | 772 | ath_dbg(common, ATH_DBG_CONFIG, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index a762cadb3ab7..34f191ec8e8c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -845,7 +845,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
845 | 845 | ||
846 | struct ath_softc *sc = file->private_data; | 846 | struct ath_softc *sc = file->private_data; |
847 | char *buf; | 847 | char *buf; |
848 | unsigned int len = 0, size = 1152; | 848 | unsigned int len = 0, size = 1400; |
849 | ssize_t retval = 0; | 849 | ssize_t retval = 0; |
850 | 850 | ||
851 | buf = kzalloc(size, GFP_KERNEL); | 851 | buf = kzalloc(size, GFP_KERNEL); |
@@ -874,6 +874,34 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
874 | "%18s : %10u\n", "DECRYPT BUSY ERR", | 874 | "%18s : %10u\n", "DECRYPT BUSY ERR", |
875 | sc->debug.stats.rxstats.decrypt_busy_err); | 875 | sc->debug.stats.rxstats.decrypt_busy_err); |
876 | 876 | ||
877 | len += snprintf(buf + len, size - len, | ||
878 | "%18s : %10d\n", "RSSI-CTL0", | ||
879 | sc->debug.stats.rxstats.rs_rssi_ctl0); | ||
880 | |||
881 | len += snprintf(buf + len, size - len, | ||
882 | "%18s : %10d\n", "RSSI-CTL1", | ||
883 | sc->debug.stats.rxstats.rs_rssi_ctl1); | ||
884 | |||
885 | len += snprintf(buf + len, size - len, | ||
886 | "%18s : %10d\n", "RSSI-CTL2", | ||
887 | sc->debug.stats.rxstats.rs_rssi_ctl2); | ||
888 | |||
889 | len += snprintf(buf + len, size - len, | ||
890 | "%18s : %10d\n", "RSSI-EXT0", | ||
891 | sc->debug.stats.rxstats.rs_rssi_ext0); | ||
892 | |||
893 | len += snprintf(buf + len, size - len, | ||
894 | "%18s : %10d\n", "RSSI-EXT1", | ||
895 | sc->debug.stats.rxstats.rs_rssi_ext1); | ||
896 | |||
897 | len += snprintf(buf + len, size - len, | ||
898 | "%18s : %10d\n", "RSSI-EXT2", | ||
899 | sc->debug.stats.rxstats.rs_rssi_ext2); | ||
900 | |||
901 | len += snprintf(buf + len, size - len, | ||
902 | "%18s : %10d\n", "Rx Antenna", | ||
903 | sc->debug.stats.rxstats.rs_antenna); | ||
904 | |||
877 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); | 905 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); |
878 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); | 906 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); |
879 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); | 907 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); |
@@ -948,6 +976,16 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
948 | RX_PHY_ERR_INC(phyerr); | 976 | RX_PHY_ERR_INC(phyerr); |
949 | } | 977 | } |
950 | 978 | ||
979 | sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; | ||
980 | sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; | ||
981 | sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; | ||
982 | |||
983 | sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; | ||
984 | sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; | ||
985 | sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; | ||
986 | |||
987 | sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; | ||
988 | |||
951 | #undef RX_STAT_INC | 989 | #undef RX_STAT_INC |
952 | #undef RX_PHY_ERR_INC | 990 | #undef RX_PHY_ERR_INC |
953 | } | 991 | } |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 59338de0ce19..1f9f8eada465 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -157,6 +157,13 @@ struct ath_rx_stats { | |||
157 | u32 post_delim_crc_err; | 157 | u32 post_delim_crc_err; |
158 | u32 decrypt_busy_err; | 158 | u32 decrypt_busy_err; |
159 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; | 159 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; |
160 | int8_t rs_rssi_ctl0; | ||
161 | int8_t rs_rssi_ctl1; | ||
162 | int8_t rs_rssi_ctl2; | ||
163 | int8_t rs_rssi_ext0; | ||
164 | int8_t rs_rssi_ext1; | ||
165 | int8_t rs_rssi_ext2; | ||
166 | u8 rs_antenna; | ||
160 | }; | 167 | }; |
161 | 168 | ||
162 | struct ath_stats { | 169 | struct ath_stats { |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index bd82447f5b78..3e316133f114 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -436,7 +436,11 @@ struct modal_eep_4k_header { | |||
436 | u8 db2_2:4, db2_3:4; | 436 | u8 db2_2:4, db2_3:4; |
437 | u8 db2_4:4, reserved:4; | 437 | u8 db2_4:4, reserved:4; |
438 | #endif | 438 | #endif |
439 | u8 futureModal[4]; | 439 | u8 tx_diversity; |
440 | u8 flc_pwr_thresh; | ||
441 | u8 bb_scale_smrt_antenna; | ||
442 | #define EEP_4K_BB_DESIRED_SCALE_MASK 0x1f | ||
443 | u8 futureModal[1]; | ||
440 | struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; | 444 | struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; |
441 | } __packed; | 445 | } __packed; |
442 | 446 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index bc77a308c901..6f714dd72365 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c | |||
@@ -781,6 +781,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | |||
781 | { | 781 | { |
782 | struct modal_eep_4k_header *pModal; | 782 | struct modal_eep_4k_header *pModal; |
783 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; | 783 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; |
784 | struct base_eep_header_4k *pBase = &eep->baseEepHeader; | ||
784 | u8 txRxAttenLocal; | 785 | u8 txRxAttenLocal; |
785 | u8 ob[5], db1[5], db2[5]; | 786 | u8 ob[5], db1[5], db2[5]; |
786 | u8 ant_div_control1, ant_div_control2; | 787 | u8 ant_div_control1, ant_div_control2; |
@@ -1003,6 +1004,31 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | |||
1003 | AR_PHY_SETTLING_SWITCH, | 1004 | AR_PHY_SETTLING_SWITCH, |
1004 | pModal->swSettleHt40); | 1005 | pModal->swSettleHt40); |
1005 | } | 1006 | } |
1007 | if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) { | ||
1008 | u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna & | ||
1009 | EEP_4K_BB_DESIRED_SCALE_MASK); | ||
1010 | if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { | ||
1011 | u32 pwrctrl, mask, clr; | ||
1012 | |||
1013 | mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); | ||
1014 | pwrctrl = mask * bb_desired_scale; | ||
1015 | clr = mask * 0x1f; | ||
1016 | REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); | ||
1017 | REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); | ||
1018 | REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); | ||
1019 | |||
1020 | mask = BIT(0)|BIT(5)|BIT(15); | ||
1021 | pwrctrl = mask * bb_desired_scale; | ||
1022 | clr = mask * 0x1f; | ||
1023 | REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); | ||
1024 | |||
1025 | mask = BIT(0)|BIT(5); | ||
1026 | pwrctrl = mask * bb_desired_scale; | ||
1027 | clr = mask * 0x1f; | ||
1028 | REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); | ||
1029 | REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); | ||
1030 | } | ||
1031 | } | ||
1006 | } | 1032 | } |
1007 | 1033 | ||
1008 | static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | 1034 | static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 2f0712ea49a6..13579752a300 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -858,35 +858,12 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, | |||
858 | { | 858 | { |
859 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; | 859 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; |
860 | struct modal_eep_ar9287_header *pModal = &eep->modalHeader; | 860 | struct modal_eep_ar9287_header *pModal = &eep->modalHeader; |
861 | u16 antWrites[AR9287_ANT_16S]; | ||
862 | u32 regChainOffset, regval; | 861 | u32 regChainOffset, regval; |
863 | u8 txRxAttenLocal; | 862 | u8 txRxAttenLocal; |
864 | int i, j, offset_num; | 863 | int i; |
865 | 864 | ||
866 | pModal = &eep->modalHeader; | 865 | pModal = &eep->modalHeader; |
867 | 866 | ||
868 | antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF); | ||
869 | antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF); | ||
870 | antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF); | ||
871 | antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF); | ||
872 | antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF); | ||
873 | antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF); | ||
874 | antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF); | ||
875 | antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF); | ||
876 | |||
877 | offset_num = 8; | ||
878 | |||
879 | for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) { | ||
880 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf); | ||
881 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3); | ||
882 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3); | ||
883 | antWrites[j++] = 0; | ||
884 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3); | ||
885 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3); | ||
886 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3); | ||
887 | antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3); | ||
888 | } | ||
889 | |||
890 | REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); | 867 | REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); |
891 | 868 | ||
892 | for (i = 0; i < AR9287_MAX_CHAINS; i++) { | 869 | for (i = 0; i < AR9287_MAX_CHAINS; i++) { |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f1b8af64569c..48bcc1a21076 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -17,11 +17,9 @@ | |||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | /* identify firmware images */ | 19 | /* identify firmware images */ |
20 | #define FIRMWARE_AR7010 "ar7010.fw" | 20 | #define FIRMWARE_AR7010_1_1 "htc_7010.fw" |
21 | #define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" | 21 | #define FIRMWARE_AR9271 "htc_9271.fw" |
22 | #define FIRMWARE_AR9271 "ar9271.fw" | ||
23 | 22 | ||
24 | MODULE_FIRMWARE(FIRMWARE_AR7010); | ||
25 | MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); | 23 | MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); |
26 | MODULE_FIRMWARE(FIRMWARE_AR9271); | 24 | MODULE_FIRMWARE(FIRMWARE_AR9271); |
27 | 25 | ||
@@ -80,7 +78,7 @@ static void hif_usb_regout_cb(struct urb *urb) | |||
80 | 78 | ||
81 | if (cmd) { | 79 | if (cmd) { |
82 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, | 80 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, |
83 | cmd->skb, 1); | 81 | cmd->skb, true); |
84 | kfree(cmd); | 82 | kfree(cmd); |
85 | } | 83 | } |
86 | 84 | ||
@@ -126,6 +124,90 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, | |||
126 | return ret; | 124 | return ret; |
127 | } | 125 | } |
128 | 126 | ||
127 | static void hif_usb_mgmt_cb(struct urb *urb) | ||
128 | { | ||
129 | struct cmd_buf *cmd = (struct cmd_buf *)urb->context; | ||
130 | struct hif_device_usb *hif_dev = cmd->hif_dev; | ||
131 | bool txok = true; | ||
132 | |||
133 | if (!cmd || !cmd->skb || !cmd->hif_dev) | ||
134 | return; | ||
135 | |||
136 | switch (urb->status) { | ||
137 | case 0: | ||
138 | break; | ||
139 | case -ENOENT: | ||
140 | case -ECONNRESET: | ||
141 | case -ENODEV: | ||
142 | case -ESHUTDOWN: | ||
143 | txok = false; | ||
144 | |||
145 | /* | ||
146 | * If the URBs are being flushed, no need to complete | ||
147 | * this packet. | ||
148 | */ | ||
149 | spin_lock(&hif_dev->tx.tx_lock); | ||
150 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { | ||
151 | spin_unlock(&hif_dev->tx.tx_lock); | ||
152 | dev_kfree_skb_any(cmd->skb); | ||
153 | kfree(cmd); | ||
154 | return; | ||
155 | } | ||
156 | spin_unlock(&hif_dev->tx.tx_lock); | ||
157 | |||
158 | break; | ||
159 | default: | ||
160 | txok = false; | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | skb_pull(cmd->skb, 4); | ||
165 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, | ||
166 | cmd->skb, txok); | ||
167 | kfree(cmd); | ||
168 | } | ||
169 | |||
170 | static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev, | ||
171 | struct sk_buff *skb) | ||
172 | { | ||
173 | struct urb *urb; | ||
174 | struct cmd_buf *cmd; | ||
175 | int ret = 0; | ||
176 | __le16 *hdr; | ||
177 | |||
178 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
179 | if (urb == NULL) | ||
180 | return -ENOMEM; | ||
181 | |||
182 | cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); | ||
183 | if (cmd == NULL) { | ||
184 | usb_free_urb(urb); | ||
185 | return -ENOMEM; | ||
186 | } | ||
187 | |||
188 | cmd->skb = skb; | ||
189 | cmd->hif_dev = hif_dev; | ||
190 | |||
191 | hdr = (__le16 *) skb_push(skb, 4); | ||
192 | *hdr++ = cpu_to_le16(skb->len - 4); | ||
193 | *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG); | ||
194 | |||
195 | usb_fill_bulk_urb(urb, hif_dev->udev, | ||
196 | usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE), | ||
197 | skb->data, skb->len, | ||
198 | hif_usb_mgmt_cb, cmd); | ||
199 | |||
200 | usb_anchor_urb(urb, &hif_dev->mgmt_submitted); | ||
201 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
202 | if (ret) { | ||
203 | usb_unanchor_urb(urb); | ||
204 | kfree(cmd); | ||
205 | } | ||
206 | usb_free_urb(urb); | ||
207 | |||
208 | return ret; | ||
209 | } | ||
210 | |||
129 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | 211 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, |
130 | struct sk_buff_head *list) | 212 | struct sk_buff_head *list) |
131 | { | 213 | { |
@@ -133,7 +215,22 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | |||
133 | 215 | ||
134 | while ((skb = __skb_dequeue(list)) != NULL) { | 216 | while ((skb = __skb_dequeue(list)) != NULL) { |
135 | dev_kfree_skb_any(skb); | 217 | dev_kfree_skb_any(skb); |
136 | TX_STAT_INC(skb_dropped); | 218 | } |
219 | } | ||
220 | |||
221 | static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, | ||
222 | struct sk_buff_head *queue, | ||
223 | bool txok) | ||
224 | { | ||
225 | struct sk_buff *skb; | ||
226 | |||
227 | while ((skb = __skb_dequeue(queue)) != NULL) { | ||
228 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
229 | skb, txok); | ||
230 | if (txok) | ||
231 | TX_STAT_INC(skb_success); | ||
232 | else | ||
233 | TX_STAT_INC(skb_failed); | ||
137 | } | 234 | } |
138 | } | 235 | } |
139 | 236 | ||
@@ -141,7 +238,7 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
141 | { | 238 | { |
142 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; | 239 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; |
143 | struct hif_device_usb *hif_dev; | 240 | struct hif_device_usb *hif_dev; |
144 | struct sk_buff *skb; | 241 | bool txok = true; |
145 | 242 | ||
146 | if (!tx_buf || !tx_buf->hif_dev) | 243 | if (!tx_buf || !tx_buf->hif_dev) |
147 | return; | 244 | return; |
@@ -155,10 +252,7 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
155 | case -ECONNRESET: | 252 | case -ECONNRESET: |
156 | case -ENODEV: | 253 | case -ENODEV: |
157 | case -ESHUTDOWN: | 254 | case -ESHUTDOWN: |
158 | /* | 255 | txok = false; |
159 | * The URB has been killed, free the SKBs. | ||
160 | */ | ||
161 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
162 | 256 | ||
163 | /* | 257 | /* |
164 | * If the URBs are being flushed, no need to add this | 258 | * If the URBs are being flushed, no need to add this |
@@ -167,41 +261,19 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
167 | spin_lock(&hif_dev->tx.tx_lock); | 261 | spin_lock(&hif_dev->tx.tx_lock); |
168 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { | 262 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { |
169 | spin_unlock(&hif_dev->tx.tx_lock); | 263 | spin_unlock(&hif_dev->tx.tx_lock); |
264 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
170 | return; | 265 | return; |
171 | } | 266 | } |
172 | spin_unlock(&hif_dev->tx.tx_lock); | 267 | spin_unlock(&hif_dev->tx.tx_lock); |
173 | 268 | ||
174 | /* | 269 | break; |
175 | * In the stop() case, this URB has to be added to | ||
176 | * the free list. | ||
177 | */ | ||
178 | goto add_free; | ||
179 | default: | 270 | default: |
271 | txok = false; | ||
180 | break; | 272 | break; |
181 | } | 273 | } |
182 | 274 | ||
183 | /* | 275 | ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, txok); |
184 | * Check if TX has been stopped, this is needed because | ||
185 | * this CB could have been invoked just after the TX lock | ||
186 | * was released in hif_stop() and kill_urb() hasn't been | ||
187 | * called yet. | ||
188 | */ | ||
189 | spin_lock(&hif_dev->tx.tx_lock); | ||
190 | if (hif_dev->tx.flags & HIF_USB_TX_STOP) { | ||
191 | spin_unlock(&hif_dev->tx.tx_lock); | ||
192 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
193 | goto add_free; | ||
194 | } | ||
195 | spin_unlock(&hif_dev->tx.tx_lock); | ||
196 | |||
197 | /* Complete the queued SKBs. */ | ||
198 | while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { | ||
199 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
200 | skb, 1); | ||
201 | TX_STAT_INC(skb_completed); | ||
202 | } | ||
203 | 276 | ||
204 | add_free: | ||
205 | /* Re-initialize the SKB queue */ | 277 | /* Re-initialize the SKB queue */ |
206 | tx_buf->len = tx_buf->offset = 0; | 278 | tx_buf->len = tx_buf->offset = 0; |
207 | __skb_queue_head_init(&tx_buf->skb_queue); | 279 | __skb_queue_head_init(&tx_buf->skb_queue); |
@@ -274,7 +346,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
274 | ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); | 346 | ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); |
275 | if (ret) { | 347 | if (ret) { |
276 | tx_buf->len = tx_buf->offset = 0; | 348 | tx_buf->len = tx_buf->offset = 0; |
277 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | 349 | ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, false); |
278 | __skb_queue_head_init(&tx_buf->skb_queue); | 350 | __skb_queue_head_init(&tx_buf->skb_queue); |
279 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); | 351 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); |
280 | hif_dev->tx.tx_buf_cnt++; | 352 | hif_dev->tx.tx_buf_cnt++; |
@@ -286,10 +358,11 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
286 | return ret; | 358 | return ret; |
287 | } | 359 | } |
288 | 360 | ||
289 | static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, | 361 | static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) |
290 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
291 | { | 362 | { |
363 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
292 | unsigned long flags; | 364 | unsigned long flags; |
365 | int ret = 0; | ||
293 | 366 | ||
294 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | 367 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); |
295 | 368 | ||
@@ -304,26 +377,36 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, | |||
304 | return -ENOMEM; | 377 | return -ENOMEM; |
305 | } | 378 | } |
306 | 379 | ||
307 | __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); | 380 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
308 | hif_dev->tx.tx_skb_cnt++; | ||
309 | 381 | ||
310 | /* Send normal frames immediately */ | 382 | tx_ctl = HTC_SKB_CB(skb); |
311 | if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL))) | 383 | |
312 | __hif_usb_tx(hif_dev); | 384 | /* Mgmt/Beacon frames don't use the TX buffer pool */ |
385 | if ((tx_ctl->type == ATH9K_HTC_MGMT) || | ||
386 | (tx_ctl->type == ATH9K_HTC_BEACON)) { | ||
387 | ret = hif_usb_send_mgmt(hif_dev, skb); | ||
388 | } | ||
389 | |||
390 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
391 | |||
392 | if ((tx_ctl->type == ATH9K_HTC_NORMAL) || | ||
393 | (tx_ctl->type == ATH9K_HTC_AMPDU)) { | ||
394 | __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); | ||
395 | hif_dev->tx.tx_skb_cnt++; | ||
396 | } | ||
313 | 397 | ||
314 | /* Check if AMPDUs have to be sent immediately */ | 398 | /* Check if AMPDUs have to be sent immediately */ |
315 | if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) && | 399 | if ((hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && |
316 | (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && | ||
317 | (hif_dev->tx.tx_skb_cnt < 2)) { | 400 | (hif_dev->tx.tx_skb_cnt < 2)) { |
318 | __hif_usb_tx(hif_dev); | 401 | __hif_usb_tx(hif_dev); |
319 | } | 402 | } |
320 | 403 | ||
321 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 404 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
322 | 405 | ||
323 | return 0; | 406 | return ret; |
324 | } | 407 | } |
325 | 408 | ||
326 | static void hif_usb_start(void *hif_handle, u8 pipe_id) | 409 | static void hif_usb_start(void *hif_handle) |
327 | { | 410 | { |
328 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 411 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
329 | unsigned long flags; | 412 | unsigned long flags; |
@@ -335,14 +418,14 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id) | |||
335 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 418 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
336 | } | 419 | } |
337 | 420 | ||
338 | static void hif_usb_stop(void *hif_handle, u8 pipe_id) | 421 | static void hif_usb_stop(void *hif_handle) |
339 | { | 422 | { |
340 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 423 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
341 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; | 424 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; |
342 | unsigned long flags; | 425 | unsigned long flags; |
343 | 426 | ||
344 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | 427 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); |
345 | ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue); | 428 | ath9k_skb_queue_complete(hif_dev, &hif_dev->tx.tx_skb_queue, false); |
346 | hif_dev->tx.tx_skb_cnt = 0; | 429 | hif_dev->tx.tx_skb_cnt = 0; |
347 | hif_dev->tx.flags |= HIF_USB_TX_STOP; | 430 | hif_dev->tx.flags |= HIF_USB_TX_STOP; |
348 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 431 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
@@ -352,17 +435,18 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id) | |||
352 | &hif_dev->tx.tx_pending, list) { | 435 | &hif_dev->tx.tx_pending, list) { |
353 | usb_kill_urb(tx_buf->urb); | 436 | usb_kill_urb(tx_buf->urb); |
354 | } | 437 | } |
438 | |||
439 | usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); | ||
355 | } | 440 | } |
356 | 441 | ||
357 | static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, | 442 | static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) |
358 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
359 | { | 443 | { |
360 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 444 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
361 | int ret = 0; | 445 | int ret = 0; |
362 | 446 | ||
363 | switch (pipe_id) { | 447 | switch (pipe_id) { |
364 | case USB_WLAN_TX_PIPE: | 448 | case USB_WLAN_TX_PIPE: |
365 | ret = hif_usb_send_tx(hif_dev, skb, tx_ctl); | 449 | ret = hif_usb_send_tx(hif_dev, skb); |
366 | break; | 450 | break; |
367 | case USB_REG_OUT_PIPE: | 451 | case USB_REG_OUT_PIPE: |
368 | ret = hif_usb_send_regout(hif_dev, skb); | 452 | ret = hif_usb_send_regout(hif_dev, skb); |
@@ -377,6 +461,40 @@ static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, | |||
377 | return ret; | 461 | return ret; |
378 | } | 462 | } |
379 | 463 | ||
464 | static inline bool check_index(struct sk_buff *skb, u8 idx) | ||
465 | { | ||
466 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
467 | |||
468 | tx_ctl = HTC_SKB_CB(skb); | ||
469 | |||
470 | if ((tx_ctl->type == ATH9K_HTC_AMPDU) && | ||
471 | (tx_ctl->sta_idx == idx)) | ||
472 | return true; | ||
473 | |||
474 | return false; | ||
475 | } | ||
476 | |||
477 | static void hif_usb_sta_drain(void *hif_handle, u8 idx) | ||
478 | { | ||
479 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | ||
480 | struct sk_buff *skb, *tmp; | ||
481 | unsigned long flags; | ||
482 | |||
483 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
484 | |||
485 | skb_queue_walk_safe(&hif_dev->tx.tx_skb_queue, skb, tmp) { | ||
486 | if (check_index(skb, idx)) { | ||
487 | __skb_unlink(skb, &hif_dev->tx.tx_skb_queue); | ||
488 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
489 | skb, false); | ||
490 | hif_dev->tx.tx_skb_cnt--; | ||
491 | TX_STAT_INC(skb_failed); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
496 | } | ||
497 | |||
380 | static struct ath9k_htc_hif hif_usb = { | 498 | static struct ath9k_htc_hif hif_usb = { |
381 | .transport = ATH9K_HIF_USB, | 499 | .transport = ATH9K_HIF_USB, |
382 | .name = "ath9k_hif_usb", | 500 | .name = "ath9k_hif_usb", |
@@ -386,6 +504,7 @@ static struct ath9k_htc_hif hif_usb = { | |||
386 | 504 | ||
387 | .start = hif_usb_start, | 505 | .start = hif_usb_start, |
388 | .stop = hif_usb_stop, | 506 | .stop = hif_usb_stop, |
507 | .sta_drain = hif_usb_sta_drain, | ||
389 | .send = hif_usb_send, | 508 | .send = hif_usb_send, |
390 | }; | 509 | }; |
391 | 510 | ||
@@ -567,6 +686,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
567 | case -ESHUTDOWN: | 686 | case -ESHUTDOWN: |
568 | goto free; | 687 | goto free; |
569 | default: | 688 | default: |
689 | skb_reset_tail_pointer(skb); | ||
690 | skb_trim(skb, 0); | ||
691 | |||
570 | goto resubmit; | 692 | goto resubmit; |
571 | } | 693 | } |
572 | 694 | ||
@@ -591,23 +713,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
591 | USB_REG_IN_PIPE), | 713 | USB_REG_IN_PIPE), |
592 | nskb->data, MAX_REG_IN_BUF_SIZE, | 714 | nskb->data, MAX_REG_IN_BUF_SIZE, |
593 | ath9k_hif_usb_reg_in_cb, nskb); | 715 | ath9k_hif_usb_reg_in_cb, nskb); |
594 | |||
595 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
596 | if (ret) { | ||
597 | kfree_skb(nskb); | ||
598 | urb->context = NULL; | ||
599 | } | ||
600 | |||
601 | return; | ||
602 | } | 716 | } |
603 | 717 | ||
604 | resubmit: | 718 | resubmit: |
605 | skb_reset_tail_pointer(skb); | 719 | usb_anchor_urb(urb, &hif_dev->reg_in_submitted); |
606 | skb_trim(skb, 0); | ||
607 | |||
608 | ret = usb_submit_urb(urb, GFP_ATOMIC); | 720 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
609 | if (ret) | 721 | if (ret) { |
722 | usb_unanchor_urb(urb); | ||
610 | goto free; | 723 | goto free; |
724 | } | ||
611 | 725 | ||
612 | return; | 726 | return; |
613 | free: | 727 | free: |
@@ -641,6 +755,8 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) | |||
641 | kfree(tx_buf->buf); | 755 | kfree(tx_buf->buf); |
642 | kfree(tx_buf); | 756 | kfree(tx_buf); |
643 | } | 757 | } |
758 | |||
759 | usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); | ||
644 | } | 760 | } |
645 | 761 | ||
646 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | 762 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) |
@@ -652,6 +768,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | |||
652 | INIT_LIST_HEAD(&hif_dev->tx.tx_pending); | 768 | INIT_LIST_HEAD(&hif_dev->tx.tx_pending); |
653 | spin_lock_init(&hif_dev->tx.tx_lock); | 769 | spin_lock_init(&hif_dev->tx.tx_lock); |
654 | __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); | 770 | __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); |
771 | init_usb_anchor(&hif_dev->mgmt_submitted); | ||
655 | 772 | ||
656 | for (i = 0; i < MAX_TX_URB_NUM; i++) { | 773 | for (i = 0; i < MAX_TX_URB_NUM; i++) { |
657 | tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); | 774 | tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); |
@@ -748,43 +865,67 @@ err_urb: | |||
748 | return ret; | 865 | return ret; |
749 | } | 866 | } |
750 | 867 | ||
751 | static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) | 868 | static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev) |
752 | { | 869 | { |
753 | if (hif_dev->reg_in_urb) { | 870 | usb_kill_anchored_urbs(&hif_dev->reg_in_submitted); |
754 | usb_kill_urb(hif_dev->reg_in_urb); | ||
755 | if (hif_dev->reg_in_urb->context) | ||
756 | kfree_skb((void *)hif_dev->reg_in_urb->context); | ||
757 | usb_free_urb(hif_dev->reg_in_urb); | ||
758 | hif_dev->reg_in_urb = NULL; | ||
759 | } | ||
760 | } | 871 | } |
761 | 872 | ||
762 | static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) | 873 | static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) |
763 | { | 874 | { |
764 | struct sk_buff *skb; | 875 | struct urb *urb = NULL; |
876 | struct sk_buff *skb = NULL; | ||
877 | int i, ret; | ||
765 | 878 | ||
766 | hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 879 | init_usb_anchor(&hif_dev->reg_in_submitted); |
767 | if (hif_dev->reg_in_urb == NULL) | ||
768 | return -ENOMEM; | ||
769 | 880 | ||
770 | skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); | 881 | for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { |
771 | if (!skb) | ||
772 | goto err; | ||
773 | 882 | ||
774 | usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, | 883 | /* Allocate URB */ |
775 | usb_rcvbulkpipe(hif_dev->udev, | 884 | urb = usb_alloc_urb(0, GFP_KERNEL); |
776 | USB_REG_IN_PIPE), | 885 | if (urb == NULL) { |
777 | skb->data, MAX_REG_IN_BUF_SIZE, | 886 | ret = -ENOMEM; |
778 | ath9k_hif_usb_reg_in_cb, skb); | 887 | goto err_urb; |
888 | } | ||
779 | 889 | ||
780 | if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) | 890 | /* Allocate buffer */ |
781 | goto err; | 891 | skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); |
892 | if (!skb) { | ||
893 | ret = -ENOMEM; | ||
894 | goto err_skb; | ||
895 | } | ||
896 | |||
897 | usb_fill_bulk_urb(urb, hif_dev->udev, | ||
898 | usb_rcvbulkpipe(hif_dev->udev, | ||
899 | USB_REG_IN_PIPE), | ||
900 | skb->data, MAX_REG_IN_BUF_SIZE, | ||
901 | ath9k_hif_usb_reg_in_cb, skb); | ||
902 | |||
903 | /* Anchor URB */ | ||
904 | usb_anchor_urb(urb, &hif_dev->reg_in_submitted); | ||
905 | |||
906 | /* Submit URB */ | ||
907 | ret = usb_submit_urb(urb, GFP_KERNEL); | ||
908 | if (ret) { | ||
909 | usb_unanchor_urb(urb); | ||
910 | goto err_submit; | ||
911 | } | ||
912 | |||
913 | /* | ||
914 | * Drop reference count. | ||
915 | * This ensures that the URB is freed when killing them. | ||
916 | */ | ||
917 | usb_free_urb(urb); | ||
918 | } | ||
782 | 919 | ||
783 | return 0; | 920 | return 0; |
784 | 921 | ||
785 | err: | 922 | err_submit: |
786 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | 923 | kfree_skb(skb); |
787 | return -ENOMEM; | 924 | err_skb: |
925 | usb_free_urb(urb); | ||
926 | err_urb: | ||
927 | ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); | ||
928 | return ret; | ||
788 | } | 929 | } |
789 | 930 | ||
790 | static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) | 931 | static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) |
@@ -801,7 +942,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) | |||
801 | goto err_rx; | 942 | goto err_rx; |
802 | 943 | ||
803 | /* Register Read */ | 944 | /* Register Read */ |
804 | if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) | 945 | if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0) |
805 | goto err_reg; | 946 | goto err_reg; |
806 | 947 | ||
807 | return 0; | 948 | return 0; |
@@ -816,7 +957,7 @@ err: | |||
816 | static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) | 957 | static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) |
817 | { | 958 | { |
818 | usb_kill_anchored_urbs(&hif_dev->regout_submitted); | 959 | usb_kill_anchored_urbs(&hif_dev->regout_submitted); |
819 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | 960 | ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); |
820 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); | 961 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); |
821 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); | 962 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); |
822 | } | 963 | } |
@@ -1026,10 +1167,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, | |||
1026 | /* Find out which firmware to load */ | 1167 | /* Find out which firmware to load */ |
1027 | 1168 | ||
1028 | if (IS_AR7010_DEVICE(id->driver_info)) | 1169 | if (IS_AR7010_DEVICE(id->driver_info)) |
1029 | if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) | 1170 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; |
1030 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; | ||
1031 | else | ||
1032 | hif_dev->fw_name = FIRMWARE_AR7010; | ||
1033 | else | 1171 | else |
1034 | hif_dev->fw_name = FIRMWARE_AR9271; | 1172 | hif_dev->fw_name = FIRMWARE_AR9271; |
1035 | 1173 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 7b9d863d4035..f59df48a86e2 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | /* FIXME: Verify these numbers (with Windows) */ | 32 | /* FIXME: Verify these numbers (with Windows) */ |
33 | #define MAX_TX_URB_NUM 8 | 33 | #define MAX_TX_URB_NUM 8 |
34 | #define MAX_TX_BUF_NUM 1024 | 34 | #define MAX_TX_BUF_NUM 256 |
35 | #define MAX_TX_BUF_SIZE 32768 | 35 | #define MAX_TX_BUF_SIZE 32768 |
36 | #define MAX_TX_AGGR_NUM 20 | 36 | #define MAX_TX_AGGR_NUM 20 |
37 | 37 | ||
@@ -40,7 +40,7 @@ | |||
40 | #define MAX_PKT_NUM_IN_TRANSFER 10 | 40 | #define MAX_PKT_NUM_IN_TRANSFER 10 |
41 | 41 | ||
42 | #define MAX_REG_OUT_URB_NUM 1 | 42 | #define MAX_REG_OUT_URB_NUM 1 |
43 | #define MAX_REG_OUT_BUF_NUM 8 | 43 | #define MAX_REG_IN_URB_NUM 64 |
44 | 44 | ||
45 | #define MAX_REG_IN_BUF_SIZE 64 | 45 | #define MAX_REG_IN_BUF_SIZE 64 |
46 | 46 | ||
@@ -90,9 +90,10 @@ struct hif_device_usb { | |||
90 | const struct firmware *firmware; | 90 | const struct firmware *firmware; |
91 | struct htc_target *htc_handle; | 91 | struct htc_target *htc_handle; |
92 | struct hif_usb_tx tx; | 92 | struct hif_usb_tx tx; |
93 | struct urb *reg_in_urb; | ||
94 | struct usb_anchor regout_submitted; | 93 | struct usb_anchor regout_submitted; |
95 | struct usb_anchor rx_submitted; | 94 | struct usb_anchor rx_submitted; |
95 | struct usb_anchor reg_in_submitted; | ||
96 | struct usb_anchor mgmt_submitted; | ||
96 | struct sk_buff *remain_skb; | 97 | struct sk_buff *remain_skb; |
97 | const char *fw_name; | 98 | const char *fw_name; |
98 | int rx_remain_len; | 99 | int rx_remain_len; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index ec47be94b74f..cc5d0a4b9da2 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -67,8 +67,11 @@ enum htc_opmode { | |||
67 | }; | 67 | }; |
68 | 68 | ||
69 | #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) | 69 | #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) |
70 | #define ATH9K_HTC_AMPDU 1 | 70 | |
71 | #define ATH9K_HTC_AMPDU 1 | ||
71 | #define ATH9K_HTC_NORMAL 2 | 72 | #define ATH9K_HTC_NORMAL 2 |
73 | #define ATH9K_HTC_BEACON 3 | ||
74 | #define ATH9K_HTC_MGMT 4 | ||
72 | 75 | ||
73 | #define ATH9K_HTC_TX_CTSONLY 0x1 | 76 | #define ATH9K_HTC_TX_CTSONLY 0x1 |
74 | #define ATH9K_HTC_TX_RTSCTS 0x2 | 77 | #define ATH9K_HTC_TX_RTSCTS 0x2 |
@@ -82,7 +85,8 @@ struct tx_frame_hdr { | |||
82 | __be32 flags; /* ATH9K_HTC_TX_* */ | 85 | __be32 flags; /* ATH9K_HTC_TX_* */ |
83 | u8 key_type; | 86 | u8 key_type; |
84 | u8 keyix; | 87 | u8 keyix; |
85 | u8 reserved[26]; | 88 | u8 cookie; |
89 | u8 pad; | ||
86 | } __packed; | 90 | } __packed; |
87 | 91 | ||
88 | struct tx_mgmt_hdr { | 92 | struct tx_mgmt_hdr { |
@@ -92,26 +96,16 @@ struct tx_mgmt_hdr { | |||
92 | u8 flags; | 96 | u8 flags; |
93 | u8 key_type; | 97 | u8 key_type; |
94 | u8 keyix; | 98 | u8 keyix; |
95 | u16 reserved; | 99 | u8 cookie; |
100 | u8 pad; | ||
96 | } __packed; | 101 | } __packed; |
97 | 102 | ||
98 | struct tx_beacon_header { | 103 | struct tx_beacon_header { |
99 | u8 len_changed; | ||
100 | u8 vif_index; | 104 | u8 vif_index; |
105 | u8 len_changed; | ||
101 | u16 rev; | 106 | u16 rev; |
102 | } __packed; | 107 | } __packed; |
103 | 108 | ||
104 | struct ath9k_htc_target_hw { | ||
105 | u32 flags; | ||
106 | u32 flags_ext; | ||
107 | u32 ampdu_limit; | ||
108 | u8 ampdu_subframes; | ||
109 | u8 tx_chainmask; | ||
110 | u8 tx_chainmask_legacy; | ||
111 | u8 rtscts_ratecode; | ||
112 | u8 protmode; | ||
113 | } __packed; | ||
114 | |||
115 | struct ath9k_htc_cap_target { | 109 | struct ath9k_htc_cap_target { |
116 | u32 flags; | 110 | u32 flags; |
117 | u32 flags_ext; | 111 | u32 flags_ext; |
@@ -121,21 +115,16 @@ struct ath9k_htc_cap_target { | |||
121 | u8 tx_chainmask_legacy; | 115 | u8 tx_chainmask_legacy; |
122 | u8 rtscts_ratecode; | 116 | u8 rtscts_ratecode; |
123 | u8 protmode; | 117 | u8 protmode; |
118 | u8 pad; | ||
124 | } __packed; | 119 | } __packed; |
125 | 120 | ||
126 | struct ath9k_htc_target_vif { | 121 | struct ath9k_htc_target_vif { |
127 | u8 index; | 122 | u8 index; |
128 | u8 des_bssid[ETH_ALEN]; | 123 | u8 opmode; |
129 | __be32 opmode; | ||
130 | u8 myaddr[ETH_ALEN]; | 124 | u8 myaddr[ETH_ALEN]; |
131 | u8 bssid[ETH_ALEN]; | ||
132 | u32 flags; | ||
133 | u32 flags_ext; | ||
134 | u16 ps_sta; | ||
135 | __be16 rtsthreshold; | ||
136 | u8 ath_cap; | 125 | u8 ath_cap; |
137 | u8 node; | 126 | __be16 rtsthreshold; |
138 | s8 mcast_rate; | 127 | u8 pad; |
139 | } __packed; | 128 | } __packed; |
140 | 129 | ||
141 | #define ATH_HTC_STA_AUTH 0x0001 | 130 | #define ATH_HTC_STA_AUTH 0x0001 |
@@ -143,27 +132,16 @@ struct ath9k_htc_target_vif { | |||
143 | #define ATH_HTC_STA_ERP 0x0004 | 132 | #define ATH_HTC_STA_ERP 0x0004 |
144 | #define ATH_HTC_STA_HT 0x0008 | 133 | #define ATH_HTC_STA_HT 0x0008 |
145 | 134 | ||
146 | /* FIXME: UAPSD variables */ | ||
147 | struct ath9k_htc_target_sta { | 135 | struct ath9k_htc_target_sta { |
148 | u16 associd; | ||
149 | u16 txpower; | ||
150 | u32 ucastkey; | ||
151 | u8 macaddr[ETH_ALEN]; | 136 | u8 macaddr[ETH_ALEN]; |
152 | u8 bssid[ETH_ALEN]; | 137 | u8 bssid[ETH_ALEN]; |
153 | u8 sta_index; | 138 | u8 sta_index; |
154 | u8 vif_index; | 139 | u8 vif_index; |
155 | u8 vif_sta; | ||
156 | __be16 flags; /* ATH_HTC_STA_* */ | ||
157 | u16 htcap; | ||
158 | u8 valid; | ||
159 | u16 capinfo; | ||
160 | struct ath9k_htc_target_hw *hw; | ||
161 | struct ath9k_htc_target_vif *vif; | ||
162 | u16 txseqmgmt; | ||
163 | u8 is_vif_sta; | 140 | u8 is_vif_sta; |
164 | u16 maxampdu; | 141 | __be16 flags; /* ATH_HTC_STA_* */ |
165 | u16 iv16; | 142 | __be16 htcap; |
166 | u32 iv32; | 143 | __be16 maxampdu; |
144 | u8 pad; | ||
167 | } __packed; | 145 | } __packed; |
168 | 146 | ||
169 | struct ath9k_htc_target_aggr { | 147 | struct ath9k_htc_target_aggr { |
@@ -197,12 +175,31 @@ struct ath9k_htc_target_rate { | |||
197 | struct ath9k_htc_rate rates; | 175 | struct ath9k_htc_rate rates; |
198 | }; | 176 | }; |
199 | 177 | ||
200 | struct ath9k_htc_target_stats { | 178 | struct ath9k_htc_target_int_stats { |
201 | __be32 tx_shortretry; | 179 | __be32 rx; |
202 | __be32 tx_longretry; | 180 | __be32 rxorn; |
203 | __be32 tx_xretries; | 181 | __be32 rxeol; |
204 | __be32 ht_txunaggr_xretry; | 182 | __be32 txurn; |
205 | __be32 ht_tx_xretries; | 183 | __be32 txto; |
184 | __be32 cst; | ||
185 | } __packed; | ||
186 | |||
187 | struct ath9k_htc_target_tx_stats { | ||
188 | __be32 xretries; | ||
189 | __be32 fifoerr; | ||
190 | __be32 filtered; | ||
191 | __be32 timer_exp; | ||
192 | __be32 shortretries; | ||
193 | __be32 longretries; | ||
194 | __be32 qnull; | ||
195 | __be32 encap_fail; | ||
196 | __be32 nobuf; | ||
197 | } __packed; | ||
198 | |||
199 | struct ath9k_htc_target_rx_stats { | ||
200 | __be32 nobuf; | ||
201 | __be32 host_send; | ||
202 | __be32 host_done; | ||
206 | } __packed; | 203 | } __packed; |
207 | 204 | ||
208 | #define ATH9K_HTC_MAX_VIF 2 | 205 | #define ATH9K_HTC_MAX_VIF 2 |
@@ -244,6 +241,8 @@ struct ath9k_htc_vif { | |||
244 | u8 index; | 241 | u8 index; |
245 | u16 seq_no; | 242 | u16 seq_no; |
246 | bool beacon_configured; | 243 | bool beacon_configured; |
244 | int bslot; | ||
245 | __le64 tsfadjust; | ||
247 | }; | 246 | }; |
248 | 247 | ||
249 | struct ath9k_vif_iter_data { | 248 | struct ath9k_vif_iter_data { |
@@ -282,23 +281,65 @@ struct ath9k_htc_rx { | |||
282 | spinlock_t rxbuflock; | 281 | spinlock_t rxbuflock; |
283 | }; | 282 | }; |
284 | 283 | ||
284 | #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ | ||
285 | #define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */ | ||
286 | #define ATH9K_HTC_TX_RESERVE 10 | ||
287 | #define ATH9K_HTC_TX_TIMEOUT_COUNT 20 | ||
288 | #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) | ||
289 | |||
290 | #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) | ||
291 | #define ATH9K_HTC_OP_TX_DRAIN BIT(1) | ||
292 | |||
293 | struct ath9k_htc_tx { | ||
294 | u8 flags; | ||
295 | int queued_cnt; | ||
296 | struct sk_buff_head mgmt_ep_queue; | ||
297 | struct sk_buff_head cab_ep_queue; | ||
298 | struct sk_buff_head data_be_queue; | ||
299 | struct sk_buff_head data_bk_queue; | ||
300 | struct sk_buff_head data_vi_queue; | ||
301 | struct sk_buff_head data_vo_queue; | ||
302 | struct sk_buff_head tx_failed; | ||
303 | DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); | ||
304 | struct timer_list cleanup_timer; | ||
305 | spinlock_t tx_lock; | ||
306 | }; | ||
307 | |||
285 | struct ath9k_htc_tx_ctl { | 308 | struct ath9k_htc_tx_ctl { |
286 | u8 type; /* ATH9K_HTC_* */ | 309 | u8 type; /* ATH9K_HTC_* */ |
310 | u8 epid; | ||
311 | u8 txok; | ||
312 | u8 sta_idx; | ||
313 | unsigned long timestamp; | ||
287 | }; | 314 | }; |
288 | 315 | ||
316 | static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) | ||
317 | { | ||
318 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
319 | |||
320 | BUILD_BUG_ON(sizeof(struct ath9k_htc_tx_ctl) > | ||
321 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE); | ||
322 | return (struct ath9k_htc_tx_ctl *) &tx_info->driver_data; | ||
323 | } | ||
324 | |||
289 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 325 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
290 | 326 | ||
291 | #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) | 327 | #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) |
292 | #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) | 328 | #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) |
329 | #define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ | ||
293 | 330 | ||
294 | #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) | 331 | #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) |
295 | 332 | ||
333 | void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | ||
334 | struct ath_htc_rx_status *rxs); | ||
335 | |||
296 | struct ath_tx_stats { | 336 | struct ath_tx_stats { |
297 | u32 buf_queued; | 337 | u32 buf_queued; |
298 | u32 buf_completed; | 338 | u32 buf_completed; |
299 | u32 skb_queued; | 339 | u32 skb_queued; |
300 | u32 skb_completed; | 340 | u32 skb_success; |
301 | u32 skb_dropped; | 341 | u32 skb_failed; |
342 | u32 cab_queued; | ||
302 | u32 queue_stats[WME_NUM_AC]; | 343 | u32 queue_stats[WME_NUM_AC]; |
303 | }; | 344 | }; |
304 | 345 | ||
@@ -306,25 +347,42 @@ struct ath_rx_stats { | |||
306 | u32 skb_allocated; | 347 | u32 skb_allocated; |
307 | u32 skb_completed; | 348 | u32 skb_completed; |
308 | u32 skb_dropped; | 349 | u32 skb_dropped; |
350 | u32 err_crc; | ||
351 | u32 err_decrypt_crc; | ||
352 | u32 err_mic; | ||
353 | u32 err_pre_delim; | ||
354 | u32 err_post_delim; | ||
355 | u32 err_decrypt_busy; | ||
356 | u32 err_phy; | ||
357 | u32 err_phy_stats[ATH9K_PHYERR_MAX]; | ||
309 | }; | 358 | }; |
310 | 359 | ||
311 | struct ath9k_debug { | 360 | struct ath9k_debug { |
312 | struct dentry *debugfs_phy; | 361 | struct dentry *debugfs_phy; |
313 | struct dentry *debugfs_tgt_stats; | 362 | struct dentry *debugfs_tgt_int_stats; |
363 | struct dentry *debugfs_tgt_tx_stats; | ||
364 | struct dentry *debugfs_tgt_rx_stats; | ||
314 | struct dentry *debugfs_xmit; | 365 | struct dentry *debugfs_xmit; |
315 | struct dentry *debugfs_recv; | 366 | struct dentry *debugfs_recv; |
367 | struct dentry *debugfs_slot; | ||
368 | struct dentry *debugfs_queue; | ||
316 | struct ath_tx_stats tx_stats; | 369 | struct ath_tx_stats tx_stats; |
317 | struct ath_rx_stats rx_stats; | 370 | struct ath_rx_stats rx_stats; |
318 | u32 txrate; | ||
319 | }; | 371 | }; |
320 | 372 | ||
321 | #else | 373 | #else |
322 | 374 | ||
323 | #define TX_STAT_INC(c) do { } while (0) | 375 | #define TX_STAT_INC(c) do { } while (0) |
324 | #define RX_STAT_INC(c) do { } while (0) | 376 | #define RX_STAT_INC(c) do { } while (0) |
377 | #define CAB_STAT_INC do { } while (0) | ||
325 | 378 | ||
326 | #define TX_QSTAT_INC(c) do { } while (0) | 379 | #define TX_QSTAT_INC(c) do { } while (0) |
327 | 380 | ||
381 | static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | ||
382 | struct ath_htc_rx_status *rxs) | ||
383 | { | ||
384 | } | ||
385 | |||
328 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | 386 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ |
329 | 387 | ||
330 | #define ATH_LED_PIN_DEF 1 | 388 | #define ATH_LED_PIN_DEF 1 |
@@ -351,10 +409,21 @@ struct ath_led { | |||
351 | int brightness; | 409 | int brightness; |
352 | }; | 410 | }; |
353 | 411 | ||
412 | #define BSTUCK_THRESHOLD 10 | ||
413 | |||
414 | /* | ||
415 | * Adjust these when the max. no of beaconing interfaces is | ||
416 | * increased. | ||
417 | */ | ||
418 | #define DEFAULT_SWBA_RESPONSE 40 /* in TUs */ | ||
419 | #define MIN_SWBA_RESPONSE 10 /* in TUs */ | ||
420 | |||
354 | struct htc_beacon_config { | 421 | struct htc_beacon_config { |
422 | struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF]; | ||
355 | u16 beacon_interval; | 423 | u16 beacon_interval; |
356 | u16 dtim_period; | 424 | u16 dtim_period; |
357 | u16 bmiss_timeout; | 425 | u16 bmiss_timeout; |
426 | u32 bmiss_cnt; | ||
358 | }; | 427 | }; |
359 | 428 | ||
360 | struct ath_btcoex { | 429 | struct ath_btcoex { |
@@ -388,6 +457,9 @@ struct ath9k_htc_priv { | |||
388 | struct htc_target *htc; | 457 | struct htc_target *htc; |
389 | struct wmi *wmi; | 458 | struct wmi *wmi; |
390 | 459 | ||
460 | u16 fw_version_major; | ||
461 | u16 fw_version_minor; | ||
462 | |||
391 | enum htc_endpoint_id wmi_cmd_ep; | 463 | enum htc_endpoint_id wmi_cmd_ep; |
392 | enum htc_endpoint_id beacon_ep; | 464 | enum htc_endpoint_id beacon_ep; |
393 | enum htc_endpoint_id cab_ep; | 465 | enum htc_endpoint_id cab_ep; |
@@ -411,27 +483,23 @@ struct ath9k_htc_priv { | |||
411 | u16 txpowlimit; | 483 | u16 txpowlimit; |
412 | u16 nvifs; | 484 | u16 nvifs; |
413 | u16 nstations; | 485 | u16 nstations; |
414 | u32 bmiss_cnt; | ||
415 | bool rearm_ani; | 486 | bool rearm_ani; |
416 | bool reconfig_beacon; | 487 | bool reconfig_beacon; |
488 | unsigned int rxfilter; | ||
417 | 489 | ||
418 | struct ath9k_hw_cal_data caldata; | 490 | struct ath9k_hw_cal_data caldata; |
491 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
419 | 492 | ||
420 | spinlock_t beacon_lock; | 493 | spinlock_t beacon_lock; |
494 | struct htc_beacon_config cur_beacon_conf; | ||
421 | 495 | ||
422 | bool tx_queues_stop; | 496 | struct ath9k_htc_rx rx; |
423 | spinlock_t tx_lock; | 497 | struct ath9k_htc_tx tx; |
424 | 498 | ||
425 | struct ieee80211_vif *vif; | ||
426 | struct htc_beacon_config cur_beacon_conf; | ||
427 | unsigned int rxfilter; | ||
428 | struct tasklet_struct swba_tasklet; | 499 | struct tasklet_struct swba_tasklet; |
429 | struct tasklet_struct rx_tasklet; | 500 | struct tasklet_struct rx_tasklet; |
430 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
431 | struct ath9k_htc_rx rx; | ||
432 | struct tasklet_struct tx_tasklet; | ||
433 | struct sk_buff_head tx_queue; | ||
434 | struct delayed_work ani_work; | 501 | struct delayed_work ani_work; |
502 | struct tasklet_struct tx_failed_tasklet; | ||
435 | struct work_struct ps_work; | 503 | struct work_struct ps_work; |
436 | struct work_struct fatal_work; | 504 | struct work_struct fatal_work; |
437 | 505 | ||
@@ -470,11 +538,18 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
470 | 538 | ||
471 | void ath9k_htc_reset(struct ath9k_htc_priv *priv); | 539 | void ath9k_htc_reset(struct ath9k_htc_priv *priv); |
472 | 540 | ||
541 | void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, | ||
542 | struct ieee80211_vif *vif); | ||
543 | void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, | ||
544 | struct ieee80211_vif *vif); | ||
545 | void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, | ||
546 | struct ieee80211_vif *vif); | ||
473 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); | 547 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); |
474 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, | 548 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, |
475 | struct ieee80211_vif *vif); | 549 | struct ieee80211_vif *vif); |
476 | void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); | 550 | void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); |
477 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); | 551 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, |
552 | struct wmi_event_swba *swba); | ||
478 | 553 | ||
479 | void ath9k_htc_rxep(void *priv, struct sk_buff *skb, | 554 | void ath9k_htc_rxep(void *priv, struct sk_buff *skb, |
480 | enum htc_endpoint_id ep_id); | 555 | enum htc_endpoint_id ep_id); |
@@ -491,14 +566,23 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv); | |||
491 | void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); | 566 | void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); |
492 | 567 | ||
493 | int ath9k_tx_init(struct ath9k_htc_priv *priv); | 568 | int ath9k_tx_init(struct ath9k_htc_priv *priv); |
494 | void ath9k_tx_tasklet(unsigned long data); | 569 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, |
495 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); | 570 | struct sk_buff *skb, u8 slot, bool is_cab); |
496 | void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); | 571 | void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); |
497 | bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); | 572 | bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); |
498 | int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); | 573 | int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); |
499 | int get_hw_qnum(u16 queue, int *hwq_map); | 574 | int get_hw_qnum(u16 queue, int *hwq_map); |
500 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | 575 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, |
501 | struct ath9k_tx_queue_info *qinfo); | 576 | struct ath9k_tx_queue_info *qinfo); |
577 | void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv); | ||
578 | void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); | ||
579 | int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv); | ||
580 | void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); | ||
581 | void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); | ||
582 | void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event); | ||
583 | void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv); | ||
584 | void ath9k_tx_failed_tasklet(unsigned long data); | ||
585 | void ath9k_htc_tx_cleanup_timer(unsigned long data); | ||
502 | 586 | ||
503 | int ath9k_rx_init(struct ath9k_htc_priv *priv); | 587 | int ath9k_rx_init(struct ath9k_htc_priv *priv); |
504 | void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); | 588 | void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 8f56158e5887..bf7ef1b7eb3f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -18,6 +18,50 @@ | |||
18 | 18 | ||
19 | #define FUDGE 2 | 19 | #define FUDGE 2 |
20 | 20 | ||
21 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | ||
22 | { | ||
23 | struct ath_hw *ah = priv->ah; | ||
24 | struct ath9k_tx_queue_info qi, qi_be; | ||
25 | |||
26 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | ||
27 | memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); | ||
28 | |||
29 | ath9k_hw_get_txq_props(ah, priv->beaconq, &qi); | ||
30 | |||
31 | if (priv->ah->opmode == NL80211_IFTYPE_AP) { | ||
32 | qi.tqi_aifs = 1; | ||
33 | qi.tqi_cwmin = 0; | ||
34 | qi.tqi_cwmax = 0; | ||
35 | } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { | ||
36 | int qnum = priv->hwq_map[WME_AC_BE]; | ||
37 | |||
38 | ath9k_hw_get_txq_props(ah, qnum, &qi_be); | ||
39 | |||
40 | qi.tqi_aifs = qi_be.tqi_aifs; | ||
41 | |||
42 | /* | ||
43 | * For WIFI Beacon Distribution | ||
44 | * Long slot time : 2x cwmin | ||
45 | * Short slot time : 4x cwmin | ||
46 | */ | ||
47 | if (ah->slottime == ATH9K_SLOT_TIME_20) | ||
48 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | ||
49 | else | ||
50 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | ||
51 | |||
52 | qi.tqi_cwmax = qi_be.tqi_cwmax; | ||
53 | |||
54 | } | ||
55 | |||
56 | if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { | ||
57 | ath_err(ath9k_hw_common(ah), | ||
58 | "Unable to update beacon queue %u!\n", priv->beaconq); | ||
59 | } else { | ||
60 | ath9k_hw_resettxqueue(ah, priv->beaconq); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | |||
21 | static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | 65 | static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, |
22 | struct htc_beacon_config *bss_conf) | 66 | struct htc_beacon_config *bss_conf) |
23 | { | 67 | { |
@@ -154,6 +198,15 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
154 | intval /= ATH9K_HTC_MAX_BCN_VIF; | 198 | intval /= ATH9K_HTC_MAX_BCN_VIF; |
155 | nexttbtt = intval; | 199 | nexttbtt = intval; |
156 | 200 | ||
201 | /* | ||
202 | * To reduce beacon misses under heavy TX load, | ||
203 | * set the beacon response time to a larger value. | ||
204 | */ | ||
205 | if (intval > DEFAULT_SWBA_RESPONSE) | ||
206 | priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; | ||
207 | else | ||
208 | priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; | ||
209 | |||
157 | if (priv->op_flags & OP_TSF_RESET) { | 210 | if (priv->op_flags & OP_TSF_RESET) { |
158 | ath9k_hw_reset_tsf(priv->ah); | 211 | ath9k_hw_reset_tsf(priv->ah); |
159 | priv->op_flags &= ~OP_TSF_RESET; | 212 | priv->op_flags &= ~OP_TSF_RESET; |
@@ -172,12 +225,16 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
172 | imask |= ATH9K_INT_SWBA; | 225 | imask |= ATH9K_INT_SWBA; |
173 | 226 | ||
174 | ath_dbg(common, ATH_DBG_CONFIG, | 227 | ath_dbg(common, ATH_DBG_CONFIG, |
175 | "AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n", | 228 | "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d " |
176 | bss_conf->beacon_interval, nexttbtt, imask); | 229 | "imask: 0x%x\n", |
230 | bss_conf->beacon_interval, nexttbtt, | ||
231 | priv->ah->config.sw_beacon_response_time, imask); | ||
232 | |||
233 | ath9k_htc_beaconq_config(priv); | ||
177 | 234 | ||
178 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 235 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
179 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); | 236 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); |
180 | priv->bmiss_cnt = 0; | 237 | priv->cur_beacon_conf.bmiss_cnt = 0; |
181 | htc_imask = cpu_to_be32(imask); | 238 | htc_imask = cpu_to_be32(imask); |
182 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | 239 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); |
183 | } | 240 | } |
@@ -205,16 +262,26 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | |||
205 | nexttbtt += intval; | 262 | nexttbtt += intval; |
206 | } while (nexttbtt < tsftu); | 263 | } while (nexttbtt < tsftu); |
207 | 264 | ||
265 | /* | ||
266 | * Only one IBSS interfce is allowed. | ||
267 | */ | ||
268 | if (intval > DEFAULT_SWBA_RESPONSE) | ||
269 | priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; | ||
270 | else | ||
271 | priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; | ||
272 | |||
208 | if (priv->op_flags & OP_ENABLE_BEACON) | 273 | if (priv->op_flags & OP_ENABLE_BEACON) |
209 | imask |= ATH9K_INT_SWBA; | 274 | imask |= ATH9K_INT_SWBA; |
210 | 275 | ||
211 | ath_dbg(common, ATH_DBG_CONFIG, | 276 | ath_dbg(common, ATH_DBG_CONFIG, |
212 | "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n", | 277 | "IBSS Beacon config, intval: %d, nexttbtt: %u, " |
213 | bss_conf->beacon_interval, nexttbtt, imask); | 278 | "resp_time: %d, imask: 0x%x\n", |
279 | bss_conf->beacon_interval, nexttbtt, | ||
280 | priv->ah->config.sw_beacon_response_time, imask); | ||
214 | 281 | ||
215 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 282 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
216 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); | 283 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); |
217 | priv->bmiss_cnt = 0; | 284 | priv->cur_beacon_conf.bmiss_cnt = 0; |
218 | htc_imask = cpu_to_be32(imask); | 285 | htc_imask = cpu_to_be32(imask); |
219 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | 286 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); |
220 | } | 287 | } |
@@ -225,38 +292,101 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | |||
225 | dev_kfree_skb_any(skb); | 292 | dev_kfree_skb_any(skb); |
226 | } | 293 | } |
227 | 294 | ||
228 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | 295 | static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, |
296 | int slot) | ||
297 | { | ||
298 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
299 | struct ieee80211_vif *vif; | ||
300 | struct sk_buff *skb; | ||
301 | struct ieee80211_hdr *hdr; | ||
302 | int padpos, padsize, ret, tx_slot; | ||
303 | |||
304 | spin_lock_bh(&priv->beacon_lock); | ||
305 | |||
306 | vif = priv->cur_beacon_conf.bslot[slot]; | ||
307 | |||
308 | skb = ieee80211_get_buffered_bc(priv->hw, vif); | ||
309 | |||
310 | while(skb) { | ||
311 | hdr = (struct ieee80211_hdr *) skb->data; | ||
312 | |||
313 | padpos = ath9k_cmn_padpos(hdr->frame_control); | ||
314 | padsize = padpos & 3; | ||
315 | if (padsize && skb->len > padpos) { | ||
316 | if (skb_headroom(skb) < padsize) { | ||
317 | dev_kfree_skb_any(skb); | ||
318 | goto next; | ||
319 | } | ||
320 | skb_push(skb, padsize); | ||
321 | memmove(skb->data, skb->data + padsize, padpos); | ||
322 | } | ||
323 | |||
324 | tx_slot = ath9k_htc_tx_get_slot(priv); | ||
325 | if (tx_slot != 0) { | ||
326 | ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n"); | ||
327 | dev_kfree_skb_any(skb); | ||
328 | goto next; | ||
329 | } | ||
330 | |||
331 | ret = ath9k_htc_tx_start(priv, skb, tx_slot, true); | ||
332 | if (ret != 0) { | ||
333 | ath9k_htc_tx_clear_slot(priv, tx_slot); | ||
334 | dev_kfree_skb_any(skb); | ||
335 | |||
336 | ath_dbg(common, ATH_DBG_XMIT, | ||
337 | "Failed to send CAB frame\n"); | ||
338 | } else { | ||
339 | spin_lock_bh(&priv->tx.tx_lock); | ||
340 | priv->tx.queued_cnt++; | ||
341 | spin_unlock_bh(&priv->tx.tx_lock); | ||
342 | } | ||
343 | next: | ||
344 | skb = ieee80211_get_buffered_bc(priv->hw, vif); | ||
345 | } | ||
346 | |||
347 | spin_unlock_bh(&priv->beacon_lock); | ||
348 | } | ||
349 | |||
350 | static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, | ||
351 | int slot) | ||
229 | { | 352 | { |
230 | struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv; | 353 | struct ath_common *common = ath9k_hw_common(priv->ah); |
354 | struct ieee80211_vif *vif; | ||
355 | struct ath9k_htc_vif *avp; | ||
231 | struct tx_beacon_header beacon_hdr; | 356 | struct tx_beacon_header beacon_hdr; |
232 | struct ath9k_htc_tx_ctl tx_ctl; | 357 | struct ath9k_htc_tx_ctl *tx_ctl; |
233 | struct ieee80211_tx_info *info; | 358 | struct ieee80211_tx_info *info; |
359 | struct ieee80211_mgmt *mgmt; | ||
234 | struct sk_buff *beacon; | 360 | struct sk_buff *beacon; |
235 | u8 *tx_fhdr; | 361 | u8 *tx_fhdr; |
362 | int ret; | ||
236 | 363 | ||
237 | memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); | 364 | memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); |
238 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); | ||
239 | |||
240 | /* FIXME: Handle BMISS */ | ||
241 | if (beacon_pending != 0) { | ||
242 | priv->bmiss_cnt++; | ||
243 | return; | ||
244 | } | ||
245 | 365 | ||
246 | spin_lock_bh(&priv->beacon_lock); | 366 | spin_lock_bh(&priv->beacon_lock); |
247 | 367 | ||
368 | vif = priv->cur_beacon_conf.bslot[slot]; | ||
369 | avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
370 | |||
248 | if (unlikely(priv->op_flags & OP_SCANNING)) { | 371 | if (unlikely(priv->op_flags & OP_SCANNING)) { |
249 | spin_unlock_bh(&priv->beacon_lock); | 372 | spin_unlock_bh(&priv->beacon_lock); |
250 | return; | 373 | return; |
251 | } | 374 | } |
252 | 375 | ||
253 | /* Get a new beacon */ | 376 | /* Get a new beacon */ |
254 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); | 377 | beacon = ieee80211_beacon_get(priv->hw, vif); |
255 | if (!beacon) { | 378 | if (!beacon) { |
256 | spin_unlock_bh(&priv->beacon_lock); | 379 | spin_unlock_bh(&priv->beacon_lock); |
257 | return; | 380 | return; |
258 | } | 381 | } |
259 | 382 | ||
383 | /* | ||
384 | * Update the TSF adjust value here, the HW will | ||
385 | * add this value for every beacon. | ||
386 | */ | ||
387 | mgmt = (struct ieee80211_mgmt *)beacon->data; | ||
388 | mgmt->u.beacon.timestamp = avp->tsfadjust; | ||
389 | |||
260 | info = IEEE80211_SKB_CB(beacon); | 390 | info = IEEE80211_SKB_CB(beacon); |
261 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 391 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
262 | struct ieee80211_hdr *hdr = | 392 | struct ieee80211_hdr *hdr = |
@@ -266,45 +396,149 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | |||
266 | hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); | 396 | hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); |
267 | } | 397 | } |
268 | 398 | ||
269 | tx_ctl.type = ATH9K_HTC_NORMAL; | 399 | tx_ctl = HTC_SKB_CB(beacon); |
400 | memset(tx_ctl, 0, sizeof(*tx_ctl)); | ||
401 | |||
402 | tx_ctl->type = ATH9K_HTC_BEACON; | ||
403 | tx_ctl->epid = priv->beacon_ep; | ||
404 | |||
270 | beacon_hdr.vif_index = avp->index; | 405 | beacon_hdr.vif_index = avp->index; |
271 | tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); | 406 | tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); |
272 | memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); | 407 | memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); |
273 | 408 | ||
274 | htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); | 409 | ret = htc_send(priv->htc, beacon); |
410 | if (ret != 0) { | ||
411 | if (ret == -ENOMEM) { | ||
412 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
413 | "Failed to send beacon, no free TX buffer\n"); | ||
414 | } | ||
415 | dev_kfree_skb_any(beacon); | ||
416 | } | ||
417 | |||
418 | spin_unlock_bh(&priv->beacon_lock); | ||
419 | } | ||
420 | |||
421 | static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv, | ||
422 | struct wmi_event_swba *swba) | ||
423 | { | ||
424 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
425 | u64 tsf; | ||
426 | u32 tsftu; | ||
427 | u16 intval; | ||
428 | int slot; | ||
429 | |||
430 | intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD; | ||
275 | 431 | ||
432 | tsf = be64_to_cpu(swba->tsf); | ||
433 | tsftu = TSF_TO_TU(tsf >> 32, tsf); | ||
434 | slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval; | ||
435 | slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1; | ||
436 | |||
437 | ath_dbg(common, ATH_DBG_BEACON, | ||
438 | "Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n", | ||
439 | slot, tsf, tsftu, intval); | ||
440 | |||
441 | return slot; | ||
442 | } | ||
443 | |||
444 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, | ||
445 | struct wmi_event_swba *swba) | ||
446 | { | ||
447 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
448 | int slot; | ||
449 | |||
450 | if (swba->beacon_pending != 0) { | ||
451 | priv->cur_beacon_conf.bmiss_cnt++; | ||
452 | if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { | ||
453 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
454 | "Beacon stuck, HW reset\n"); | ||
455 | ieee80211_queue_work(priv->hw, | ||
456 | &priv->fatal_work); | ||
457 | } | ||
458 | return; | ||
459 | } | ||
460 | |||
461 | if (priv->cur_beacon_conf.bmiss_cnt) { | ||
462 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
463 | "Resuming beacon xmit after %u misses\n", | ||
464 | priv->cur_beacon_conf.bmiss_cnt); | ||
465 | priv->cur_beacon_conf.bmiss_cnt = 0; | ||
466 | } | ||
467 | |||
468 | slot = ath9k_htc_choose_bslot(priv, swba); | ||
469 | spin_lock_bh(&priv->beacon_lock); | ||
470 | if (priv->cur_beacon_conf.bslot[slot] == NULL) { | ||
471 | spin_unlock_bh(&priv->beacon_lock); | ||
472 | return; | ||
473 | } | ||
276 | spin_unlock_bh(&priv->beacon_lock); | 474 | spin_unlock_bh(&priv->beacon_lock); |
475 | |||
476 | ath9k_htc_send_buffered(priv, slot); | ||
477 | ath9k_htc_send_beacon(priv, slot); | ||
277 | } | 478 | } |
278 | 479 | ||
279 | /* Currently, only for IBSS */ | 480 | void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, |
280 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | 481 | struct ieee80211_vif *vif) |
281 | { | 482 | { |
282 | struct ath_hw *ah = priv->ah; | 483 | struct ath_common *common = ath9k_hw_common(priv->ah); |
283 | struct ath9k_tx_queue_info qi, qi_be; | 484 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; |
284 | int qnum = priv->hwq_map[WME_AC_BE]; | 485 | int i = 0; |
285 | 486 | ||
286 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | 487 | spin_lock_bh(&priv->beacon_lock); |
287 | memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); | 488 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) { |
489 | if (priv->cur_beacon_conf.bslot[i] == NULL) { | ||
490 | avp->bslot = i; | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | priv->cur_beacon_conf.bslot[avp->bslot] = vif; | ||
496 | spin_unlock_bh(&priv->beacon_lock); | ||
497 | |||
498 | ath_dbg(common, ATH_DBG_CONFIG, | ||
499 | "Added interface at beacon slot: %d\n", avp->bslot); | ||
500 | } | ||
501 | |||
502 | void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, | ||
503 | struct ieee80211_vif *vif) | ||
504 | { | ||
505 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
506 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
507 | |||
508 | spin_lock_bh(&priv->beacon_lock); | ||
509 | priv->cur_beacon_conf.bslot[avp->bslot] = NULL; | ||
510 | spin_unlock_bh(&priv->beacon_lock); | ||
511 | |||
512 | ath_dbg(common, ATH_DBG_CONFIG, | ||
513 | "Removed interface at beacon slot: %d\n", avp->bslot); | ||
514 | } | ||
288 | 515 | ||
289 | ath9k_hw_get_txq_props(ah, qnum, &qi_be); | 516 | /* |
517 | * Calculate the TSF adjustment value for all slots | ||
518 | * other than zero. | ||
519 | */ | ||
520 | void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, | ||
521 | struct ieee80211_vif *vif) | ||
522 | { | ||
523 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
524 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
525 | struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; | ||
526 | u64 tsfadjust; | ||
527 | |||
528 | if (avp->bslot == 0) | ||
529 | return; | ||
290 | 530 | ||
291 | qi.tqi_aifs = qi_be.tqi_aifs; | 531 | /* |
292 | /* For WIFI Beacon Distribution | 532 | * The beacon interval cannot be different for multi-AP mode, |
293 | * Long slot time : 2x cwmin | 533 | * and we reach here only for VIF slots greater than zero, |
294 | * Short slot time : 4x cwmin | 534 | * so beacon_interval is guaranteed to be set in cur_conf. |
295 | */ | 535 | */ |
296 | if (ah->slottime == ATH9K_SLOT_TIME_20) | 536 | tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF; |
297 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | 537 | avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); |
298 | else | ||
299 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | ||
300 | qi.tqi_cwmax = qi_be.tqi_cwmax; | ||
301 | 538 | ||
302 | if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { | 539 | ath_dbg(common, ATH_DBG_CONFIG, |
303 | ath_err(ath9k_hw_common(ah), | 540 | "tsfadjust is: %llu for bslot: %d\n", |
304 | "Unable to update beacon queue %u!\n", qnum); | 541 | (unsigned long long)tsfadjust, avp->bslot); |
305 | } else { | ||
306 | ath9k_hw_resettxqueue(ah, priv->beaconq); | ||
307 | } | ||
308 | } | 542 | } |
309 | 543 | ||
310 | static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 544 | static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c new file mode 100644 index 000000000000..8d0de60e0c27 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c | |||
@@ -0,0 +1,531 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "htc.h" | ||
18 | |||
19 | static struct dentry *ath9k_debugfs_root; | ||
20 | |||
21 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
22 | { | ||
23 | file->private_data = inode->i_private; | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, | ||
28 | size_t count, loff_t *ppos) | ||
29 | { | ||
30 | struct ath9k_htc_priv *priv = file->private_data; | ||
31 | struct ath9k_htc_target_int_stats cmd_rsp; | ||
32 | char buf[512]; | ||
33 | unsigned int len = 0; | ||
34 | int ret = 0; | ||
35 | |||
36 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
37 | |||
38 | WMI_CMD(WMI_INT_STATS_CMDID); | ||
39 | if (ret) | ||
40 | return -EINVAL; | ||
41 | |||
42 | len += snprintf(buf + len, sizeof(buf) - len, | ||
43 | "%20s : %10u\n", "RX", | ||
44 | be32_to_cpu(cmd_rsp.rx)); | ||
45 | |||
46 | len += snprintf(buf + len, sizeof(buf) - len, | ||
47 | "%20s : %10u\n", "RXORN", | ||
48 | be32_to_cpu(cmd_rsp.rxorn)); | ||
49 | |||
50 | len += snprintf(buf + len, sizeof(buf) - len, | ||
51 | "%20s : %10u\n", "RXEOL", | ||
52 | be32_to_cpu(cmd_rsp.rxeol)); | ||
53 | |||
54 | len += snprintf(buf + len, sizeof(buf) - len, | ||
55 | "%20s : %10u\n", "TXURN", | ||
56 | be32_to_cpu(cmd_rsp.txurn)); | ||
57 | |||
58 | len += snprintf(buf + len, sizeof(buf) - len, | ||
59 | "%20s : %10u\n", "TXTO", | ||
60 | be32_to_cpu(cmd_rsp.txto)); | ||
61 | |||
62 | len += snprintf(buf + len, sizeof(buf) - len, | ||
63 | "%20s : %10u\n", "CST", | ||
64 | be32_to_cpu(cmd_rsp.cst)); | ||
65 | |||
66 | if (len > sizeof(buf)) | ||
67 | len = sizeof(buf); | ||
68 | |||
69 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
70 | } | ||
71 | |||
72 | static const struct file_operations fops_tgt_int_stats = { | ||
73 | .read = read_file_tgt_int_stats, | ||
74 | .open = ath9k_debugfs_open, | ||
75 | .owner = THIS_MODULE, | ||
76 | .llseek = default_llseek, | ||
77 | }; | ||
78 | |||
79 | static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, | ||
80 | size_t count, loff_t *ppos) | ||
81 | { | ||
82 | struct ath9k_htc_priv *priv = file->private_data; | ||
83 | struct ath9k_htc_target_tx_stats cmd_rsp; | ||
84 | char buf[512]; | ||
85 | unsigned int len = 0; | ||
86 | int ret = 0; | ||
87 | |||
88 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
89 | |||
90 | WMI_CMD(WMI_TX_STATS_CMDID); | ||
91 | if (ret) | ||
92 | return -EINVAL; | ||
93 | |||
94 | len += snprintf(buf + len, sizeof(buf) - len, | ||
95 | "%20s : %10u\n", "Xretries", | ||
96 | be32_to_cpu(cmd_rsp.xretries)); | ||
97 | |||
98 | len += snprintf(buf + len, sizeof(buf) - len, | ||
99 | "%20s : %10u\n", "FifoErr", | ||
100 | be32_to_cpu(cmd_rsp.fifoerr)); | ||
101 | |||
102 | len += snprintf(buf + len, sizeof(buf) - len, | ||
103 | "%20s : %10u\n", "Filtered", | ||
104 | be32_to_cpu(cmd_rsp.filtered)); | ||
105 | |||
106 | len += snprintf(buf + len, sizeof(buf) - len, | ||
107 | "%20s : %10u\n", "TimerExp", | ||
108 | be32_to_cpu(cmd_rsp.timer_exp)); | ||
109 | |||
110 | len += snprintf(buf + len, sizeof(buf) - len, | ||
111 | "%20s : %10u\n", "ShortRetries", | ||
112 | be32_to_cpu(cmd_rsp.shortretries)); | ||
113 | |||
114 | len += snprintf(buf + len, sizeof(buf) - len, | ||
115 | "%20s : %10u\n", "LongRetries", | ||
116 | be32_to_cpu(cmd_rsp.longretries)); | ||
117 | |||
118 | len += snprintf(buf + len, sizeof(buf) - len, | ||
119 | "%20s : %10u\n", "QueueNull", | ||
120 | be32_to_cpu(cmd_rsp.qnull)); | ||
121 | |||
122 | len += snprintf(buf + len, sizeof(buf) - len, | ||
123 | "%20s : %10u\n", "EncapFail", | ||
124 | be32_to_cpu(cmd_rsp.encap_fail)); | ||
125 | |||
126 | len += snprintf(buf + len, sizeof(buf) - len, | ||
127 | "%20s : %10u\n", "NoBuf", | ||
128 | be32_to_cpu(cmd_rsp.nobuf)); | ||
129 | |||
130 | if (len > sizeof(buf)) | ||
131 | len = sizeof(buf); | ||
132 | |||
133 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
134 | } | ||
135 | |||
136 | static const struct file_operations fops_tgt_tx_stats = { | ||
137 | .read = read_file_tgt_tx_stats, | ||
138 | .open = ath9k_debugfs_open, | ||
139 | .owner = THIS_MODULE, | ||
140 | .llseek = default_llseek, | ||
141 | }; | ||
142 | |||
143 | static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, | ||
144 | size_t count, loff_t *ppos) | ||
145 | { | ||
146 | struct ath9k_htc_priv *priv = file->private_data; | ||
147 | struct ath9k_htc_target_rx_stats cmd_rsp; | ||
148 | char buf[512]; | ||
149 | unsigned int len = 0; | ||
150 | int ret = 0; | ||
151 | |||
152 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
153 | |||
154 | WMI_CMD(WMI_RX_STATS_CMDID); | ||
155 | if (ret) | ||
156 | return -EINVAL; | ||
157 | |||
158 | len += snprintf(buf + len, sizeof(buf) - len, | ||
159 | "%20s : %10u\n", "NoBuf", | ||
160 | be32_to_cpu(cmd_rsp.nobuf)); | ||
161 | |||
162 | len += snprintf(buf + len, sizeof(buf) - len, | ||
163 | "%20s : %10u\n", "HostSend", | ||
164 | be32_to_cpu(cmd_rsp.host_send)); | ||
165 | |||
166 | len += snprintf(buf + len, sizeof(buf) - len, | ||
167 | "%20s : %10u\n", "HostDone", | ||
168 | be32_to_cpu(cmd_rsp.host_done)); | ||
169 | |||
170 | if (len > sizeof(buf)) | ||
171 | len = sizeof(buf); | ||
172 | |||
173 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
174 | } | ||
175 | |||
176 | static const struct file_operations fops_tgt_rx_stats = { | ||
177 | .read = read_file_tgt_rx_stats, | ||
178 | .open = ath9k_debugfs_open, | ||
179 | .owner = THIS_MODULE, | ||
180 | .llseek = default_llseek, | ||
181 | }; | ||
182 | |||
183 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | ||
184 | size_t count, loff_t *ppos) | ||
185 | { | ||
186 | struct ath9k_htc_priv *priv = file->private_data; | ||
187 | char buf[512]; | ||
188 | unsigned int len = 0; | ||
189 | |||
190 | len += snprintf(buf + len, sizeof(buf) - len, | ||
191 | "%20s : %10u\n", "Buffers queued", | ||
192 | priv->debug.tx_stats.buf_queued); | ||
193 | len += snprintf(buf + len, sizeof(buf) - len, | ||
194 | "%20s : %10u\n", "Buffers completed", | ||
195 | priv->debug.tx_stats.buf_completed); | ||
196 | len += snprintf(buf + len, sizeof(buf) - len, | ||
197 | "%20s : %10u\n", "SKBs queued", | ||
198 | priv->debug.tx_stats.skb_queued); | ||
199 | len += snprintf(buf + len, sizeof(buf) - len, | ||
200 | "%20s : %10u\n", "SKBs success", | ||
201 | priv->debug.tx_stats.skb_success); | ||
202 | len += snprintf(buf + len, sizeof(buf) - len, | ||
203 | "%20s : %10u\n", "SKBs failed", | ||
204 | priv->debug.tx_stats.skb_failed); | ||
205 | len += snprintf(buf + len, sizeof(buf) - len, | ||
206 | "%20s : %10u\n", "CAB queued", | ||
207 | priv->debug.tx_stats.cab_queued); | ||
208 | |||
209 | len += snprintf(buf + len, sizeof(buf) - len, | ||
210 | "%20s : %10u\n", "BE queued", | ||
211 | priv->debug.tx_stats.queue_stats[WME_AC_BE]); | ||
212 | len += snprintf(buf + len, sizeof(buf) - len, | ||
213 | "%20s : %10u\n", "BK queued", | ||
214 | priv->debug.tx_stats.queue_stats[WME_AC_BK]); | ||
215 | len += snprintf(buf + len, sizeof(buf) - len, | ||
216 | "%20s : %10u\n", "VI queued", | ||
217 | priv->debug.tx_stats.queue_stats[WME_AC_VI]); | ||
218 | len += snprintf(buf + len, sizeof(buf) - len, | ||
219 | "%20s : %10u\n", "VO queued", | ||
220 | priv->debug.tx_stats.queue_stats[WME_AC_VO]); | ||
221 | |||
222 | if (len > sizeof(buf)) | ||
223 | len = sizeof(buf); | ||
224 | |||
225 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
226 | } | ||
227 | |||
228 | static const struct file_operations fops_xmit = { | ||
229 | .read = read_file_xmit, | ||
230 | .open = ath9k_debugfs_open, | ||
231 | .owner = THIS_MODULE, | ||
232 | .llseek = default_llseek, | ||
233 | }; | ||
234 | |||
235 | void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | ||
236 | struct ath_htc_rx_status *rxs) | ||
237 | { | ||
238 | #define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++ | ||
239 | |||
240 | if (rxs->rs_status & ATH9K_RXERR_CRC) | ||
241 | priv->debug.rx_stats.err_crc++; | ||
242 | if (rxs->rs_status & ATH9K_RXERR_DECRYPT) | ||
243 | priv->debug.rx_stats.err_decrypt_crc++; | ||
244 | if (rxs->rs_status & ATH9K_RXERR_MIC) | ||
245 | priv->debug.rx_stats.err_mic++; | ||
246 | if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE) | ||
247 | priv->debug.rx_stats.err_pre_delim++; | ||
248 | if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST) | ||
249 | priv->debug.rx_stats.err_post_delim++; | ||
250 | if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY) | ||
251 | priv->debug.rx_stats.err_decrypt_busy++; | ||
252 | |||
253 | if (rxs->rs_status & ATH9K_RXERR_PHY) { | ||
254 | priv->debug.rx_stats.err_phy++; | ||
255 | if (rxs->rs_phyerr < ATH9K_PHYERR_MAX) | ||
256 | RX_PHY_ERR_INC(rxs->rs_phyerr); | ||
257 | } | ||
258 | |||
259 | #undef RX_PHY_ERR_INC | ||
260 | } | ||
261 | |||
262 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | ||
263 | size_t count, loff_t *ppos) | ||
264 | { | ||
265 | #define PHY_ERR(s, p) \ | ||
266 | len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \ | ||
267 | priv->debug.rx_stats.err_phy_stats[p]); | ||
268 | |||
269 | struct ath9k_htc_priv *priv = file->private_data; | ||
270 | char *buf; | ||
271 | unsigned int len = 0, size = 1500; | ||
272 | ssize_t retval = 0; | ||
273 | |||
274 | buf = kzalloc(size, GFP_KERNEL); | ||
275 | if (buf == NULL) | ||
276 | return -ENOMEM; | ||
277 | |||
278 | len += snprintf(buf + len, size - len, | ||
279 | "%20s : %10u\n", "SKBs allocated", | ||
280 | priv->debug.rx_stats.skb_allocated); | ||
281 | len += snprintf(buf + len, size - len, | ||
282 | "%20s : %10u\n", "SKBs completed", | ||
283 | priv->debug.rx_stats.skb_completed); | ||
284 | len += snprintf(buf + len, size - len, | ||
285 | "%20s : %10u\n", "SKBs Dropped", | ||
286 | priv->debug.rx_stats.skb_dropped); | ||
287 | |||
288 | len += snprintf(buf + len, size - len, | ||
289 | "%20s : %10u\n", "CRC ERR", | ||
290 | priv->debug.rx_stats.err_crc); | ||
291 | len += snprintf(buf + len, size - len, | ||
292 | "%20s : %10u\n", "DECRYPT CRC ERR", | ||
293 | priv->debug.rx_stats.err_decrypt_crc); | ||
294 | len += snprintf(buf + len, size - len, | ||
295 | "%20s : %10u\n", "MIC ERR", | ||
296 | priv->debug.rx_stats.err_mic); | ||
297 | len += snprintf(buf + len, size - len, | ||
298 | "%20s : %10u\n", "PRE-DELIM CRC ERR", | ||
299 | priv->debug.rx_stats.err_pre_delim); | ||
300 | len += snprintf(buf + len, size - len, | ||
301 | "%20s : %10u\n", "POST-DELIM CRC ERR", | ||
302 | priv->debug.rx_stats.err_post_delim); | ||
303 | len += snprintf(buf + len, size - len, | ||
304 | "%20s : %10u\n", "DECRYPT BUSY ERR", | ||
305 | priv->debug.rx_stats.err_decrypt_busy); | ||
306 | len += snprintf(buf + len, size - len, | ||
307 | "%20s : %10u\n", "TOTAL PHY ERR", | ||
308 | priv->debug.rx_stats.err_phy); | ||
309 | |||
310 | |||
311 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); | ||
312 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); | ||
313 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); | ||
314 | PHY_ERR("RATE", ATH9K_PHYERR_RATE); | ||
315 | PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH); | ||
316 | PHY_ERR("RADAR", ATH9K_PHYERR_RADAR); | ||
317 | PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE); | ||
318 | PHY_ERR("TOR", ATH9K_PHYERR_TOR); | ||
319 | PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING); | ||
320 | PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); | ||
321 | PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); | ||
322 | PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); | ||
323 | PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP); | ||
324 | PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE); | ||
325 | PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART); | ||
326 | PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT); | ||
327 | PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING); | ||
328 | PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC); | ||
329 | PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL); | ||
330 | PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE); | ||
331 | PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART); | ||
332 | PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); | ||
333 | PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP); | ||
334 | PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR); | ||
335 | PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); | ||
336 | PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); | ||
337 | |||
338 | if (len > size) | ||
339 | len = size; | ||
340 | |||
341 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
342 | kfree(buf); | ||
343 | |||
344 | return retval; | ||
345 | |||
346 | #undef PHY_ERR | ||
347 | } | ||
348 | |||
349 | static const struct file_operations fops_recv = { | ||
350 | .read = read_file_recv, | ||
351 | .open = ath9k_debugfs_open, | ||
352 | .owner = THIS_MODULE, | ||
353 | .llseek = default_llseek, | ||
354 | }; | ||
355 | |||
356 | static ssize_t read_file_slot(struct file *file, char __user *user_buf, | ||
357 | size_t count, loff_t *ppos) | ||
358 | { | ||
359 | struct ath9k_htc_priv *priv = file->private_data; | ||
360 | char buf[512]; | ||
361 | unsigned int len = 0; | ||
362 | |||
363 | spin_lock_bh(&priv->tx.tx_lock); | ||
364 | |||
365 | len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : "); | ||
366 | |||
367 | len += bitmap_scnprintf(buf + len, sizeof(buf) - len, | ||
368 | priv->tx.tx_slot, MAX_TX_BUF_NUM); | ||
369 | |||
370 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | ||
371 | |||
372 | len += snprintf(buf + len, sizeof(buf) - len, | ||
373 | "Used slots : %d\n", | ||
374 | bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM)); | ||
375 | |||
376 | spin_unlock_bh(&priv->tx.tx_lock); | ||
377 | |||
378 | if (len > sizeof(buf)) | ||
379 | len = sizeof(buf); | ||
380 | |||
381 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
382 | } | ||
383 | |||
384 | static const struct file_operations fops_slot = { | ||
385 | .read = read_file_slot, | ||
386 | .open = ath9k_debugfs_open, | ||
387 | .owner = THIS_MODULE, | ||
388 | .llseek = default_llseek, | ||
389 | }; | ||
390 | |||
391 | static ssize_t read_file_queue(struct file *file, char __user *user_buf, | ||
392 | size_t count, loff_t *ppos) | ||
393 | { | ||
394 | struct ath9k_htc_priv *priv = file->private_data; | ||
395 | char buf[512]; | ||
396 | unsigned int len = 0; | ||
397 | |||
398 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
399 | "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); | ||
400 | |||
401 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
402 | "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); | ||
403 | |||
404 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
405 | "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); | ||
406 | |||
407 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
408 | "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); | ||
409 | |||
410 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
411 | "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); | ||
412 | |||
413 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
414 | "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); | ||
415 | |||
416 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
417 | "Failed queue", skb_queue_len(&priv->tx.tx_failed)); | ||
418 | |||
419 | spin_lock_bh(&priv->tx.tx_lock); | ||
420 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
421 | "Queued count", priv->tx.queued_cnt); | ||
422 | spin_unlock_bh(&priv->tx.tx_lock); | ||
423 | |||
424 | if (len > sizeof(buf)) | ||
425 | len = sizeof(buf); | ||
426 | |||
427 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
428 | |||
429 | } | ||
430 | |||
431 | static const struct file_operations fops_queue = { | ||
432 | .read = read_file_queue, | ||
433 | .open = ath9k_debugfs_open, | ||
434 | .owner = THIS_MODULE, | ||
435 | .llseek = default_llseek, | ||
436 | }; | ||
437 | |||
438 | int ath9k_htc_init_debug(struct ath_hw *ah) | ||
439 | { | ||
440 | struct ath_common *common = ath9k_hw_common(ah); | ||
441 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
442 | |||
443 | if (!ath9k_debugfs_root) | ||
444 | return -ENOENT; | ||
445 | |||
446 | priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), | ||
447 | ath9k_debugfs_root); | ||
448 | if (!priv->debug.debugfs_phy) | ||
449 | goto err; | ||
450 | |||
451 | priv->debug.debugfs_tgt_int_stats = debugfs_create_file("tgt_int_stats", | ||
452 | S_IRUSR, | ||
453 | priv->debug.debugfs_phy, | ||
454 | priv, &fops_tgt_int_stats); | ||
455 | if (!priv->debug.debugfs_tgt_int_stats) | ||
456 | goto err; | ||
457 | |||
458 | priv->debug.debugfs_tgt_tx_stats = debugfs_create_file("tgt_tx_stats", | ||
459 | S_IRUSR, | ||
460 | priv->debug.debugfs_phy, | ||
461 | priv, &fops_tgt_tx_stats); | ||
462 | if (!priv->debug.debugfs_tgt_tx_stats) | ||
463 | goto err; | ||
464 | |||
465 | priv->debug.debugfs_tgt_rx_stats = debugfs_create_file("tgt_rx_stats", | ||
466 | S_IRUSR, | ||
467 | priv->debug.debugfs_phy, | ||
468 | priv, &fops_tgt_rx_stats); | ||
469 | if (!priv->debug.debugfs_tgt_rx_stats) | ||
470 | goto err; | ||
471 | |||
472 | priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, | ||
473 | priv->debug.debugfs_phy, | ||
474 | priv, &fops_xmit); | ||
475 | if (!priv->debug.debugfs_xmit) | ||
476 | goto err; | ||
477 | |||
478 | priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, | ||
479 | priv->debug.debugfs_phy, | ||
480 | priv, &fops_recv); | ||
481 | if (!priv->debug.debugfs_recv) | ||
482 | goto err; | ||
483 | |||
484 | priv->debug.debugfs_slot = debugfs_create_file("slot", S_IRUSR, | ||
485 | priv->debug.debugfs_phy, | ||
486 | priv, &fops_slot); | ||
487 | if (!priv->debug.debugfs_slot) | ||
488 | goto err; | ||
489 | |||
490 | priv->debug.debugfs_queue = debugfs_create_file("queue", S_IRUSR, | ||
491 | priv->debug.debugfs_phy, | ||
492 | priv, &fops_queue); | ||
493 | if (!priv->debug.debugfs_queue) | ||
494 | goto err; | ||
495 | |||
496 | return 0; | ||
497 | |||
498 | err: | ||
499 | ath9k_htc_exit_debug(ah); | ||
500 | return -ENOMEM; | ||
501 | } | ||
502 | |||
503 | void ath9k_htc_exit_debug(struct ath_hw *ah) | ||
504 | { | ||
505 | struct ath_common *common = ath9k_hw_common(ah); | ||
506 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
507 | |||
508 | debugfs_remove(priv->debug.debugfs_queue); | ||
509 | debugfs_remove(priv->debug.debugfs_slot); | ||
510 | debugfs_remove(priv->debug.debugfs_recv); | ||
511 | debugfs_remove(priv->debug.debugfs_xmit); | ||
512 | debugfs_remove(priv->debug.debugfs_tgt_int_stats); | ||
513 | debugfs_remove(priv->debug.debugfs_tgt_tx_stats); | ||
514 | debugfs_remove(priv->debug.debugfs_tgt_rx_stats); | ||
515 | debugfs_remove(priv->debug.debugfs_phy); | ||
516 | } | ||
517 | |||
518 | int ath9k_htc_debug_create_root(void) | ||
519 | { | ||
520 | ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
521 | if (!ath9k_debugfs_root) | ||
522 | return -ENOENT; | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | void ath9k_htc_debug_remove_root(void) | ||
528 | { | ||
529 | debugfs_remove(ath9k_debugfs_root); | ||
530 | ath9k_debugfs_root = NULL; | ||
531 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 7e630a81b453..dc0b33d01210 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | |||
@@ -398,9 +398,9 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw) | |||
398 | 398 | ||
399 | /* Start TX */ | 399 | /* Start TX */ |
400 | htc_start(priv->htc); | 400 | htc_start(priv->htc); |
401 | spin_lock_bh(&priv->tx_lock); | 401 | spin_lock_bh(&priv->tx.tx_lock); |
402 | priv->tx_queues_stop = false; | 402 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; |
403 | spin_unlock_bh(&priv->tx_lock); | 403 | spin_unlock_bh(&priv->tx.tx_lock); |
404 | ieee80211_wake_queues(hw); | 404 | ieee80211_wake_queues(hw); |
405 | 405 | ||
406 | WMI_CMD(WMI_ENABLE_INTR_CMDID); | 406 | WMI_CMD(WMI_ENABLE_INTR_CMDID); |
@@ -429,13 +429,15 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw) | |||
429 | 429 | ||
430 | /* Stop TX */ | 430 | /* Stop TX */ |
431 | ieee80211_stop_queues(hw); | 431 | ieee80211_stop_queues(hw); |
432 | htc_stop(priv->htc); | 432 | ath9k_htc_tx_drain(priv); |
433 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 433 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
434 | skb_queue_purge(&priv->tx_queue); | ||
435 | 434 | ||
436 | /* Stop RX */ | 435 | /* Stop RX */ |
437 | WMI_CMD(WMI_STOP_RECV_CMDID); | 436 | WMI_CMD(WMI_STOP_RECV_CMDID); |
438 | 437 | ||
438 | /* Clear the WMI event queue */ | ||
439 | ath9k_wmi_event_drain(priv); | ||
440 | |||
439 | /* | 441 | /* |
440 | * The MIB counters have to be disabled here, | 442 | * The MIB counters have to be disabled here, |
441 | * since the target doesn't do it. | 443 | * since the target doesn't do it. |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 8303b34bdc90..22736eb901cf 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -643,7 +643,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
643 | { | 643 | { |
644 | struct ath_hw *ah = NULL; | 644 | struct ath_hw *ah = NULL; |
645 | struct ath_common *common; | 645 | struct ath_common *common; |
646 | int ret = 0, csz = 0; | 646 | int i, ret = 0, csz = 0; |
647 | 647 | ||
648 | priv->op_flags |= OP_INVALID; | 648 | priv->op_flags |= OP_INVALID; |
649 | 649 | ||
@@ -671,20 +671,19 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
671 | common->priv = priv; | 671 | common->priv = priv; |
672 | common->debug_mask = ath9k_debug; | 672 | common->debug_mask = ath9k_debug; |
673 | 673 | ||
674 | spin_lock_init(&priv->wmi->wmi_lock); | ||
675 | spin_lock_init(&priv->beacon_lock); | 674 | spin_lock_init(&priv->beacon_lock); |
676 | spin_lock_init(&priv->tx_lock); | 675 | spin_lock_init(&priv->tx.tx_lock); |
677 | mutex_init(&priv->mutex); | 676 | mutex_init(&priv->mutex); |
678 | mutex_init(&priv->htc_pm_lock); | 677 | mutex_init(&priv->htc_pm_lock); |
679 | tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet, | ||
680 | (unsigned long)priv); | ||
681 | tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, | 678 | tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, |
682 | (unsigned long)priv); | 679 | (unsigned long)priv); |
683 | tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, | 680 | tasklet_init(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet, |
684 | (unsigned long)priv); | 681 | (unsigned long)priv); |
685 | INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); | 682 | INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); |
686 | INIT_WORK(&priv->ps_work, ath9k_ps_work); | 683 | INIT_WORK(&priv->ps_work, ath9k_ps_work); |
687 | INIT_WORK(&priv->fatal_work, ath9k_fatal_work); | 684 | INIT_WORK(&priv->fatal_work, ath9k_fatal_work); |
685 | setup_timer(&priv->tx.cleanup_timer, ath9k_htc_tx_cleanup_timer, | ||
686 | (unsigned long)priv); | ||
688 | 687 | ||
689 | /* | 688 | /* |
690 | * Cache line size is used to size and align various | 689 | * Cache line size is used to size and align various |
@@ -711,6 +710,9 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
711 | if (ret) | 710 | if (ret) |
712 | goto err_queues; | 711 | goto err_queues; |
713 | 712 | ||
713 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) | ||
714 | priv->cur_beacon_conf.bslot[i] = NULL; | ||
715 | |||
714 | ath9k_init_crypto(priv); | 716 | ath9k_init_crypto(priv); |
715 | ath9k_init_channels_rates(priv); | 717 | ath9k_init_channels_rates(priv); |
716 | ath9k_init_misc(priv); | 718 | ath9k_init_misc(priv); |
@@ -745,11 +747,15 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
745 | IEEE80211_HW_HAS_RATE_CONTROL | | 747 | IEEE80211_HW_HAS_RATE_CONTROL | |
746 | IEEE80211_HW_RX_INCLUDES_FCS | | 748 | IEEE80211_HW_RX_INCLUDES_FCS | |
747 | IEEE80211_HW_SUPPORTS_PS | | 749 | IEEE80211_HW_SUPPORTS_PS | |
748 | IEEE80211_HW_PS_NULLFUNC_STACK; | 750 | IEEE80211_HW_PS_NULLFUNC_STACK | |
751 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | ||
749 | 752 | ||
750 | hw->wiphy->interface_modes = | 753 | hw->wiphy->interface_modes = |
751 | BIT(NL80211_IFTYPE_STATION) | | 754 | BIT(NL80211_IFTYPE_STATION) | |
752 | BIT(NL80211_IFTYPE_ADHOC); | 755 | BIT(NL80211_IFTYPE_ADHOC) | |
756 | BIT(NL80211_IFTYPE_AP) | | ||
757 | BIT(NL80211_IFTYPE_P2P_GO) | | ||
758 | BIT(NL80211_IFTYPE_P2P_CLIENT); | ||
753 | 759 | ||
754 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 760 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
755 | 761 | ||
@@ -782,6 +788,32 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
782 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | 788 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); |
783 | } | 789 | } |
784 | 790 | ||
791 | static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) | ||
792 | { | ||
793 | struct ieee80211_hw *hw = priv->hw; | ||
794 | struct wmi_fw_version cmd_rsp; | ||
795 | int ret; | ||
796 | |||
797 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
798 | |||
799 | WMI_CMD(WMI_GET_FW_VERSION); | ||
800 | if (ret) | ||
801 | return -EINVAL; | ||
802 | |||
803 | priv->fw_version_major = be16_to_cpu(cmd_rsp.major); | ||
804 | priv->fw_version_minor = be16_to_cpu(cmd_rsp.minor); | ||
805 | |||
806 | snprintf(hw->wiphy->fw_version, ETHTOOL_BUSINFO_LEN, "%d.%d", | ||
807 | priv->fw_version_major, | ||
808 | priv->fw_version_minor); | ||
809 | |||
810 | dev_info(priv->dev, "ath9k_htc: FW Version: %d.%d\n", | ||
811 | priv->fw_version_major, | ||
812 | priv->fw_version_minor); | ||
813 | |||
814 | return 0; | ||
815 | } | ||
816 | |||
785 | static int ath9k_init_device(struct ath9k_htc_priv *priv, | 817 | static int ath9k_init_device(struct ath9k_htc_priv *priv, |
786 | u16 devid, char *product, u32 drv_info) | 818 | u16 devid, char *product, u32 drv_info) |
787 | { | 819 | { |
@@ -801,6 +833,10 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
801 | common = ath9k_hw_common(ah); | 833 | common = ath9k_hw_common(ah); |
802 | ath9k_set_hw_capab(priv, hw); | 834 | ath9k_set_hw_capab(priv, hw); |
803 | 835 | ||
836 | error = ath9k_init_firmware_version(priv); | ||
837 | if (error != 0) | ||
838 | goto err_fw; | ||
839 | |||
804 | /* Initialize regulatory */ | 840 | /* Initialize regulatory */ |
805 | error = ath_regd_init(&common->regulatory, priv->hw->wiphy, | 841 | error = ath_regd_init(&common->regulatory, priv->hw->wiphy, |
806 | ath9k_reg_notifier); | 842 | ath9k_reg_notifier); |
@@ -861,6 +897,8 @@ err_rx: | |||
861 | err_tx: | 897 | err_tx: |
862 | /* Nothing */ | 898 | /* Nothing */ |
863 | err_regd: | 899 | err_regd: |
900 | /* Nothing */ | ||
901 | err_fw: | ||
864 | ath9k_deinit_priv(priv); | 902 | ath9k_deinit_priv(priv); |
865 | err_init: | 903 | err_init: |
866 | return error; | 904 | return error; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index db8c0c044e9e..4de38643cb53 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -16,10 +16,6 @@ | |||
16 | 16 | ||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
20 | static struct dentry *ath9k_debugfs_root; | ||
21 | #endif | ||
22 | |||
23 | /*************/ | 19 | /*************/ |
24 | /* Utilities */ | 20 | /* Utilities */ |
25 | /*************/ | 21 | /*************/ |
@@ -197,11 +193,16 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) | |||
197 | 193 | ||
198 | ath9k_htc_stop_ani(priv); | 194 | ath9k_htc_stop_ani(priv); |
199 | ieee80211_stop_queues(priv->hw); | 195 | ieee80211_stop_queues(priv->hw); |
200 | htc_stop(priv->htc); | 196 | |
197 | del_timer_sync(&priv->tx.cleanup_timer); | ||
198 | ath9k_htc_tx_drain(priv); | ||
199 | |||
201 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 200 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
202 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 201 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
203 | WMI_CMD(WMI_STOP_RECV_CMDID); | 202 | WMI_CMD(WMI_STOP_RECV_CMDID); |
204 | 203 | ||
204 | ath9k_wmi_event_drain(priv); | ||
205 | |||
205 | caldata = &priv->caldata; | 206 | caldata = &priv->caldata; |
206 | ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); | 207 | ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); |
207 | if (ret) { | 208 | if (ret) { |
@@ -225,6 +226,9 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) | |||
225 | ath9k_htc_vif_reconfig(priv); | 226 | ath9k_htc_vif_reconfig(priv); |
226 | ieee80211_wake_queues(priv->hw); | 227 | ieee80211_wake_queues(priv->hw); |
227 | 228 | ||
229 | mod_timer(&priv->tx.cleanup_timer, | ||
230 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
231 | |||
228 | ath9k_htc_ps_restore(priv); | 232 | ath9k_htc_ps_restore(priv); |
229 | mutex_unlock(&priv->mutex); | 233 | mutex_unlock(&priv->mutex); |
230 | } | 234 | } |
@@ -250,11 +254,16 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
250 | fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); | 254 | fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); |
251 | 255 | ||
252 | ath9k_htc_ps_wakeup(priv); | 256 | ath9k_htc_ps_wakeup(priv); |
253 | htc_stop(priv->htc); | 257 | |
258 | del_timer_sync(&priv->tx.cleanup_timer); | ||
259 | ath9k_htc_tx_drain(priv); | ||
260 | |||
254 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 261 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
255 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 262 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
256 | WMI_CMD(WMI_STOP_RECV_CMDID); | 263 | WMI_CMD(WMI_STOP_RECV_CMDID); |
257 | 264 | ||
265 | ath9k_wmi_event_drain(priv); | ||
266 | |||
258 | ath_dbg(common, ATH_DBG_CONFIG, | 267 | ath_dbg(common, ATH_DBG_CONFIG, |
259 | "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", | 268 | "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", |
260 | priv->ah->curchan->channel, | 269 | priv->ah->curchan->channel, |
@@ -263,6 +272,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
263 | 272 | ||
264 | if (!fastcc) | 273 | if (!fastcc) |
265 | caldata = &priv->caldata; | 274 | caldata = &priv->caldata; |
275 | |||
266 | ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); | 276 | ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); |
267 | if (ret) { | 277 | if (ret) { |
268 | ath_err(common, | 278 | ath_err(common, |
@@ -296,6 +306,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
296 | !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) | 306 | !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) |
297 | ath9k_htc_vif_reconfig(priv); | 307 | ath9k_htc_vif_reconfig(priv); |
298 | 308 | ||
309 | mod_timer(&priv->tx.cleanup_timer, | ||
310 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
311 | |||
299 | err: | 312 | err: |
300 | ath9k_htc_ps_restore(priv); | 313 | ath9k_htc_ps_restore(priv); |
301 | return ret; | 314 | return ret; |
@@ -349,7 +362,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) | |||
349 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); | 362 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); |
350 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); | 363 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); |
351 | 364 | ||
352 | hvif.opmode = cpu_to_be32(HTC_M_MONITOR); | 365 | hvif.opmode = HTC_M_MONITOR; |
353 | hvif.index = ffz(priv->vif_slot); | 366 | hvif.index = ffz(priv->vif_slot); |
354 | 367 | ||
355 | WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); | 368 | WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); |
@@ -382,7 +395,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) | |||
382 | tsta.is_vif_sta = 1; | 395 | tsta.is_vif_sta = 1; |
383 | tsta.sta_index = sta_idx; | 396 | tsta.sta_index = sta_idx; |
384 | tsta.vif_index = hvif.index; | 397 | tsta.vif_index = hvif.index; |
385 | tsta.maxampdu = 0xffff; | 398 | tsta.maxampdu = cpu_to_be16(0xffff); |
386 | 399 | ||
387 | WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); | 400 | WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); |
388 | if (ret) { | 401 | if (ret) { |
@@ -463,9 +476,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
463 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | 476 | ista = (struct ath9k_htc_sta *) sta->drv_priv; |
464 | memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); | 477 | memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); |
465 | memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); | 478 | memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); |
466 | tsta.associd = common->curaid; | ||
467 | tsta.is_vif_sta = 0; | 479 | tsta.is_vif_sta = 0; |
468 | tsta.valid = true; | ||
469 | ista->index = sta_idx; | 480 | ista->index = sta_idx; |
470 | } else { | 481 | } else { |
471 | memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); | 482 | memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); |
@@ -474,7 +485,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
474 | 485 | ||
475 | tsta.sta_index = sta_idx; | 486 | tsta.sta_index = sta_idx; |
476 | tsta.vif_index = avp->index; | 487 | tsta.vif_index = avp->index; |
477 | tsta.maxampdu = 0xffff; | 488 | tsta.maxampdu = cpu_to_be16(0xffff); |
478 | if (sta && sta->ht_cap.ht_supported) | 489 | if (sta && sta->ht_cap.ht_supported) |
479 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); | 490 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); |
480 | 491 | ||
@@ -709,218 +720,13 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, | |||
709 | (aggr.aggr_enable) ? "Starting" : "Stopping", | 720 | (aggr.aggr_enable) ? "Starting" : "Stopping", |
710 | sta->addr, tid); | 721 | sta->addr, tid); |
711 | 722 | ||
712 | spin_lock_bh(&priv->tx_lock); | 723 | spin_lock_bh(&priv->tx.tx_lock); |
713 | ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; | 724 | ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; |
714 | spin_unlock_bh(&priv->tx_lock); | 725 | spin_unlock_bh(&priv->tx.tx_lock); |
715 | 726 | ||
716 | return ret; | 727 | return ret; |
717 | } | 728 | } |
718 | 729 | ||
719 | /*********/ | ||
720 | /* DEBUG */ | ||
721 | /*********/ | ||
722 | |||
723 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
724 | |||
725 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
726 | { | ||
727 | file->private_data = inode->i_private; | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, | ||
732 | size_t count, loff_t *ppos) | ||
733 | { | ||
734 | struct ath9k_htc_priv *priv = file->private_data; | ||
735 | struct ath9k_htc_target_stats cmd_rsp; | ||
736 | char buf[512]; | ||
737 | unsigned int len = 0; | ||
738 | int ret = 0; | ||
739 | |||
740 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
741 | |||
742 | WMI_CMD(WMI_TGT_STATS_CMDID); | ||
743 | if (ret) | ||
744 | return -EINVAL; | ||
745 | |||
746 | |||
747 | len += snprintf(buf + len, sizeof(buf) - len, | ||
748 | "%19s : %10u\n", "TX Short Retries", | ||
749 | be32_to_cpu(cmd_rsp.tx_shortretry)); | ||
750 | len += snprintf(buf + len, sizeof(buf) - len, | ||
751 | "%19s : %10u\n", "TX Long Retries", | ||
752 | be32_to_cpu(cmd_rsp.tx_longretry)); | ||
753 | len += snprintf(buf + len, sizeof(buf) - len, | ||
754 | "%19s : %10u\n", "TX Xretries", | ||
755 | be32_to_cpu(cmd_rsp.tx_xretries)); | ||
756 | len += snprintf(buf + len, sizeof(buf) - len, | ||
757 | "%19s : %10u\n", "TX Unaggr. Xretries", | ||
758 | be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); | ||
759 | len += snprintf(buf + len, sizeof(buf) - len, | ||
760 | "%19s : %10u\n", "TX Xretries (HT)", | ||
761 | be32_to_cpu(cmd_rsp.ht_tx_xretries)); | ||
762 | len += snprintf(buf + len, sizeof(buf) - len, | ||
763 | "%19s : %10u\n", "TX Rate", priv->debug.txrate); | ||
764 | |||
765 | if (len > sizeof(buf)) | ||
766 | len = sizeof(buf); | ||
767 | |||
768 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
769 | } | ||
770 | |||
771 | static const struct file_operations fops_tgt_stats = { | ||
772 | .read = read_file_tgt_stats, | ||
773 | .open = ath9k_debugfs_open, | ||
774 | .owner = THIS_MODULE, | ||
775 | .llseek = default_llseek, | ||
776 | }; | ||
777 | |||
778 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | ||
779 | size_t count, loff_t *ppos) | ||
780 | { | ||
781 | struct ath9k_htc_priv *priv = file->private_data; | ||
782 | char buf[512]; | ||
783 | unsigned int len = 0; | ||
784 | |||
785 | len += snprintf(buf + len, sizeof(buf) - len, | ||
786 | "%20s : %10u\n", "Buffers queued", | ||
787 | priv->debug.tx_stats.buf_queued); | ||
788 | len += snprintf(buf + len, sizeof(buf) - len, | ||
789 | "%20s : %10u\n", "Buffers completed", | ||
790 | priv->debug.tx_stats.buf_completed); | ||
791 | len += snprintf(buf + len, sizeof(buf) - len, | ||
792 | "%20s : %10u\n", "SKBs queued", | ||
793 | priv->debug.tx_stats.skb_queued); | ||
794 | len += snprintf(buf + len, sizeof(buf) - len, | ||
795 | "%20s : %10u\n", "SKBs completed", | ||
796 | priv->debug.tx_stats.skb_completed); | ||
797 | len += snprintf(buf + len, sizeof(buf) - len, | ||
798 | "%20s : %10u\n", "SKBs dropped", | ||
799 | priv->debug.tx_stats.skb_dropped); | ||
800 | |||
801 | len += snprintf(buf + len, sizeof(buf) - len, | ||
802 | "%20s : %10u\n", "BE queued", | ||
803 | priv->debug.tx_stats.queue_stats[WME_AC_BE]); | ||
804 | len += snprintf(buf + len, sizeof(buf) - len, | ||
805 | "%20s : %10u\n", "BK queued", | ||
806 | priv->debug.tx_stats.queue_stats[WME_AC_BK]); | ||
807 | len += snprintf(buf + len, sizeof(buf) - len, | ||
808 | "%20s : %10u\n", "VI queued", | ||
809 | priv->debug.tx_stats.queue_stats[WME_AC_VI]); | ||
810 | len += snprintf(buf + len, sizeof(buf) - len, | ||
811 | "%20s : %10u\n", "VO queued", | ||
812 | priv->debug.tx_stats.queue_stats[WME_AC_VO]); | ||
813 | |||
814 | if (len > sizeof(buf)) | ||
815 | len = sizeof(buf); | ||
816 | |||
817 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
818 | } | ||
819 | |||
820 | static const struct file_operations fops_xmit = { | ||
821 | .read = read_file_xmit, | ||
822 | .open = ath9k_debugfs_open, | ||
823 | .owner = THIS_MODULE, | ||
824 | .llseek = default_llseek, | ||
825 | }; | ||
826 | |||
827 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | ||
828 | size_t count, loff_t *ppos) | ||
829 | { | ||
830 | struct ath9k_htc_priv *priv = file->private_data; | ||
831 | char buf[512]; | ||
832 | unsigned int len = 0; | ||
833 | |||
834 | len += snprintf(buf + len, sizeof(buf) - len, | ||
835 | "%20s : %10u\n", "SKBs allocated", | ||
836 | priv->debug.rx_stats.skb_allocated); | ||
837 | len += snprintf(buf + len, sizeof(buf) - len, | ||
838 | "%20s : %10u\n", "SKBs completed", | ||
839 | priv->debug.rx_stats.skb_completed); | ||
840 | len += snprintf(buf + len, sizeof(buf) - len, | ||
841 | "%20s : %10u\n", "SKBs Dropped", | ||
842 | priv->debug.rx_stats.skb_dropped); | ||
843 | |||
844 | if (len > sizeof(buf)) | ||
845 | len = sizeof(buf); | ||
846 | |||
847 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
848 | } | ||
849 | |||
850 | static const struct file_operations fops_recv = { | ||
851 | .read = read_file_recv, | ||
852 | .open = ath9k_debugfs_open, | ||
853 | .owner = THIS_MODULE, | ||
854 | .llseek = default_llseek, | ||
855 | }; | ||
856 | |||
857 | int ath9k_htc_init_debug(struct ath_hw *ah) | ||
858 | { | ||
859 | struct ath_common *common = ath9k_hw_common(ah); | ||
860 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
861 | |||
862 | if (!ath9k_debugfs_root) | ||
863 | return -ENOENT; | ||
864 | |||
865 | priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), | ||
866 | ath9k_debugfs_root); | ||
867 | if (!priv->debug.debugfs_phy) | ||
868 | goto err; | ||
869 | |||
870 | priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, | ||
871 | priv->debug.debugfs_phy, | ||
872 | priv, &fops_tgt_stats); | ||
873 | if (!priv->debug.debugfs_tgt_stats) | ||
874 | goto err; | ||
875 | |||
876 | |||
877 | priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, | ||
878 | priv->debug.debugfs_phy, | ||
879 | priv, &fops_xmit); | ||
880 | if (!priv->debug.debugfs_xmit) | ||
881 | goto err; | ||
882 | |||
883 | priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, | ||
884 | priv->debug.debugfs_phy, | ||
885 | priv, &fops_recv); | ||
886 | if (!priv->debug.debugfs_recv) | ||
887 | goto err; | ||
888 | |||
889 | return 0; | ||
890 | |||
891 | err: | ||
892 | ath9k_htc_exit_debug(ah); | ||
893 | return -ENOMEM; | ||
894 | } | ||
895 | |||
896 | void ath9k_htc_exit_debug(struct ath_hw *ah) | ||
897 | { | ||
898 | struct ath_common *common = ath9k_hw_common(ah); | ||
899 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
900 | |||
901 | debugfs_remove(priv->debug.debugfs_recv); | ||
902 | debugfs_remove(priv->debug.debugfs_xmit); | ||
903 | debugfs_remove(priv->debug.debugfs_tgt_stats); | ||
904 | debugfs_remove(priv->debug.debugfs_phy); | ||
905 | } | ||
906 | |||
907 | int ath9k_htc_debug_create_root(void) | ||
908 | { | ||
909 | ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
910 | if (!ath9k_debugfs_root) | ||
911 | return -ENOENT; | ||
912 | |||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | void ath9k_htc_debug_remove_root(void) | ||
917 | { | ||
918 | debugfs_remove(ath9k_debugfs_root); | ||
919 | ath9k_debugfs_root = NULL; | ||
920 | } | ||
921 | |||
922 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | ||
923 | |||
924 | /*******/ | 730 | /*******/ |
925 | /* ANI */ | 731 | /* ANI */ |
926 | /*******/ | 732 | /*******/ |
@@ -1040,7 +846,8 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1040 | { | 846 | { |
1041 | struct ieee80211_hdr *hdr; | 847 | struct ieee80211_hdr *hdr; |
1042 | struct ath9k_htc_priv *priv = hw->priv; | 848 | struct ath9k_htc_priv *priv = hw->priv; |
1043 | int padpos, padsize, ret; | 849 | struct ath_common *common = ath9k_hw_common(priv->ah); |
850 | int padpos, padsize, ret, slot; | ||
1044 | 851 | ||
1045 | hdr = (struct ieee80211_hdr *) skb->data; | 852 | hdr = (struct ieee80211_hdr *) skb->data; |
1046 | 853 | ||
@@ -1048,30 +855,32 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1048 | padpos = ath9k_cmn_padpos(hdr->frame_control); | 855 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
1049 | padsize = padpos & 3; | 856 | padsize = padpos & 3; |
1050 | if (padsize && skb->len > padpos) { | 857 | if (padsize && skb->len > padpos) { |
1051 | if (skb_headroom(skb) < padsize) | 858 | if (skb_headroom(skb) < padsize) { |
859 | ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n"); | ||
1052 | goto fail_tx; | 860 | goto fail_tx; |
861 | } | ||
1053 | skb_push(skb, padsize); | 862 | skb_push(skb, padsize); |
1054 | memmove(skb->data, skb->data + padsize, padpos); | 863 | memmove(skb->data, skb->data + padsize, padpos); |
1055 | } | 864 | } |
1056 | 865 | ||
1057 | ret = ath9k_htc_tx_start(priv, skb); | 866 | slot = ath9k_htc_tx_get_slot(priv); |
1058 | if (ret != 0) { | 867 | if (slot < 0) { |
1059 | if (ret == -ENOMEM) { | 868 | ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n"); |
1060 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
1061 | "Stopping TX queues\n"); | ||
1062 | ieee80211_stop_queues(hw); | ||
1063 | spin_lock_bh(&priv->tx_lock); | ||
1064 | priv->tx_queues_stop = true; | ||
1065 | spin_unlock_bh(&priv->tx_lock); | ||
1066 | } else { | ||
1067 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
1068 | "Tx failed\n"); | ||
1069 | } | ||
1070 | goto fail_tx; | 869 | goto fail_tx; |
1071 | } | 870 | } |
1072 | 871 | ||
872 | ret = ath9k_htc_tx_start(priv, skb, slot, false); | ||
873 | if (ret != 0) { | ||
874 | ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n"); | ||
875 | goto clear_slot; | ||
876 | } | ||
877 | |||
878 | ath9k_htc_check_stop_queues(priv); | ||
879 | |||
1073 | return; | 880 | return; |
1074 | 881 | ||
882 | clear_slot: | ||
883 | ath9k_htc_tx_clear_slot(priv, slot); | ||
1075 | fail_tx: | 884 | fail_tx: |
1076 | dev_kfree_skb_any(skb); | 885 | dev_kfree_skb_any(skb); |
1077 | } | 886 | } |
@@ -1130,12 +939,15 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1130 | priv->op_flags &= ~OP_INVALID; | 939 | priv->op_flags &= ~OP_INVALID; |
1131 | htc_start(priv->htc); | 940 | htc_start(priv->htc); |
1132 | 941 | ||
1133 | spin_lock_bh(&priv->tx_lock); | 942 | spin_lock_bh(&priv->tx.tx_lock); |
1134 | priv->tx_queues_stop = false; | 943 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; |
1135 | spin_unlock_bh(&priv->tx_lock); | 944 | spin_unlock_bh(&priv->tx.tx_lock); |
1136 | 945 | ||
1137 | ieee80211_wake_queues(hw); | 946 | ieee80211_wake_queues(hw); |
1138 | 947 | ||
948 | mod_timer(&priv->tx.cleanup_timer, | ||
949 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
950 | |||
1139 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { | 951 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { |
1140 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | 952 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
1141 | AR_STOMP_LOW_WLAN_WGHT); | 953 | AR_STOMP_LOW_WLAN_WGHT); |
@@ -1164,16 +976,16 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1164 | } | 976 | } |
1165 | 977 | ||
1166 | ath9k_htc_ps_wakeup(priv); | 978 | ath9k_htc_ps_wakeup(priv); |
1167 | htc_stop(priv->htc); | 979 | |
1168 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 980 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
1169 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 981 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
1170 | WMI_CMD(WMI_STOP_RECV_CMDID); | 982 | WMI_CMD(WMI_STOP_RECV_CMDID); |
1171 | 983 | ||
1172 | tasklet_kill(&priv->swba_tasklet); | ||
1173 | tasklet_kill(&priv->rx_tasklet); | 984 | tasklet_kill(&priv->rx_tasklet); |
1174 | tasklet_kill(&priv->tx_tasklet); | ||
1175 | 985 | ||
1176 | skb_queue_purge(&priv->tx_queue); | 986 | del_timer_sync(&priv->tx.cleanup_timer); |
987 | ath9k_htc_tx_drain(priv); | ||
988 | ath9k_wmi_event_drain(priv); | ||
1177 | 989 | ||
1178 | mutex_unlock(&priv->mutex); | 990 | mutex_unlock(&priv->mutex); |
1179 | 991 | ||
@@ -1245,13 +1057,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1245 | 1057 | ||
1246 | switch (vif->type) { | 1058 | switch (vif->type) { |
1247 | case NL80211_IFTYPE_STATION: | 1059 | case NL80211_IFTYPE_STATION: |
1248 | hvif.opmode = cpu_to_be32(HTC_M_STA); | 1060 | hvif.opmode = HTC_M_STA; |
1249 | break; | 1061 | break; |
1250 | case NL80211_IFTYPE_ADHOC: | 1062 | case NL80211_IFTYPE_ADHOC: |
1251 | hvif.opmode = cpu_to_be32(HTC_M_IBSS); | 1063 | hvif.opmode = HTC_M_IBSS; |
1252 | break; | 1064 | break; |
1253 | case NL80211_IFTYPE_AP: | 1065 | case NL80211_IFTYPE_AP: |
1254 | hvif.opmode = cpu_to_be32(HTC_M_HOSTAP); | 1066 | hvif.opmode = HTC_M_HOSTAP; |
1255 | break; | 1067 | break; |
1256 | default: | 1068 | default: |
1257 | ath_err(common, | 1069 | ath_err(common, |
@@ -1281,14 +1093,20 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1281 | 1093 | ||
1282 | priv->vif_slot |= (1 << avp->index); | 1094 | priv->vif_slot |= (1 << avp->index); |
1283 | priv->nvifs++; | 1095 | priv->nvifs++; |
1284 | priv->vif = vif; | ||
1285 | 1096 | ||
1286 | INC_VIF(priv, vif->type); | 1097 | INC_VIF(priv, vif->type); |
1098 | |||
1099 | if ((vif->type == NL80211_IFTYPE_AP) || | ||
1100 | (vif->type == NL80211_IFTYPE_ADHOC)) | ||
1101 | ath9k_htc_assign_bslot(priv, vif); | ||
1102 | |||
1287 | ath9k_htc_set_opmode(priv); | 1103 | ath9k_htc_set_opmode(priv); |
1288 | 1104 | ||
1289 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && | 1105 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && |
1290 | !(priv->op_flags & OP_ANI_RUNNING)) | 1106 | !(priv->op_flags & OP_ANI_RUNNING)) { |
1107 | ath9k_hw_set_tsfadjust(priv->ah, 1); | ||
1291 | ath9k_htc_start_ani(priv); | 1108 | ath9k_htc_start_ani(priv); |
1109 | } | ||
1292 | 1110 | ||
1293 | ath_dbg(common, ATH_DBG_CONFIG, | 1111 | ath_dbg(common, ATH_DBG_CONFIG, |
1294 | "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); | 1112 | "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); |
@@ -1321,9 +1139,13 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
1321 | priv->vif_slot &= ~(1 << avp->index); | 1139 | priv->vif_slot &= ~(1 << avp->index); |
1322 | 1140 | ||
1323 | ath9k_htc_remove_station(priv, vif, NULL); | 1141 | ath9k_htc_remove_station(priv, vif, NULL); |
1324 | priv->vif = NULL; | ||
1325 | 1142 | ||
1326 | DEC_VIF(priv, vif->type); | 1143 | DEC_VIF(priv, vif->type); |
1144 | |||
1145 | if ((vif->type == NL80211_IFTYPE_AP) || | ||
1146 | (vif->type == NL80211_IFTYPE_ADHOC)) | ||
1147 | ath9k_htc_remove_bslot(priv, vif); | ||
1148 | |||
1327 | ath9k_htc_set_opmode(priv); | 1149 | ath9k_htc_set_opmode(priv); |
1328 | 1150 | ||
1329 | /* | 1151 | /* |
@@ -1493,10 +1315,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, | |||
1493 | struct ieee80211_sta *sta) | 1315 | struct ieee80211_sta *sta) |
1494 | { | 1316 | { |
1495 | struct ath9k_htc_priv *priv = hw->priv; | 1317 | struct ath9k_htc_priv *priv = hw->priv; |
1318 | struct ath9k_htc_sta *ista; | ||
1496 | int ret; | 1319 | int ret; |
1497 | 1320 | ||
1498 | mutex_lock(&priv->mutex); | 1321 | mutex_lock(&priv->mutex); |
1499 | ath9k_htc_ps_wakeup(priv); | 1322 | ath9k_htc_ps_wakeup(priv); |
1323 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
1324 | htc_sta_drain(priv->htc, ista->index); | ||
1500 | ret = ath9k_htc_remove_station(priv, vif, sta); | 1325 | ret = ath9k_htc_remove_station(priv, vif, sta); |
1501 | ath9k_htc_ps_restore(priv); | 1326 | ath9k_htc_ps_restore(priv); |
1502 | mutex_unlock(&priv->mutex); | 1327 | mutex_unlock(&priv->mutex); |
@@ -1644,6 +1469,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1644 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { | 1469 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { |
1645 | ath_dbg(common, ATH_DBG_CONFIG, | 1470 | ath_dbg(common, ATH_DBG_CONFIG, |
1646 | "Beacon enabled for BSS: %pM\n", bss_conf->bssid); | 1471 | "Beacon enabled for BSS: %pM\n", bss_conf->bssid); |
1472 | ath9k_htc_set_tsfadjust(priv, vif); | ||
1647 | priv->op_flags |= OP_ENABLE_BEACON; | 1473 | priv->op_flags |= OP_ENABLE_BEACON; |
1648 | ath9k_htc_beacon_config(priv, vif); | 1474 | ath9k_htc_beacon_config(priv, vif); |
1649 | } | 1475 | } |
@@ -1758,9 +1584,9 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
1758 | break; | 1584 | break; |
1759 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 1585 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
1760 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | 1586 | ista = (struct ath9k_htc_sta *) sta->drv_priv; |
1761 | spin_lock_bh(&priv->tx_lock); | 1587 | spin_lock_bh(&priv->tx.tx_lock); |
1762 | ista->tid_state[tid] = AGGR_OPERATIONAL; | 1588 | ista->tid_state[tid] = AGGR_OPERATIONAL; |
1763 | spin_unlock_bh(&priv->tx_lock); | 1589 | spin_unlock_bh(&priv->tx.tx_lock); |
1764 | break; | 1590 | break; |
1765 | default: | 1591 | default: |
1766 | ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); | 1592 | ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 4a4f27ba96af..723a3a9c5cd9 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -53,6 +53,138 @@ int get_hw_qnum(u16 queue, int *hwq_map) | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv) | ||
57 | { | ||
58 | spin_lock_bh(&priv->tx.tx_lock); | ||
59 | priv->tx.queued_cnt++; | ||
60 | if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) && | ||
61 | !(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { | ||
62 | priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP; | ||
63 | ieee80211_stop_queues(priv->hw); | ||
64 | } | ||
65 | spin_unlock_bh(&priv->tx.tx_lock); | ||
66 | } | ||
67 | |||
68 | void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv) | ||
69 | { | ||
70 | spin_lock_bh(&priv->tx.tx_lock); | ||
71 | if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) && | ||
72 | (priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { | ||
73 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; | ||
74 | ieee80211_wake_queues(priv->hw); | ||
75 | } | ||
76 | spin_unlock_bh(&priv->tx.tx_lock); | ||
77 | } | ||
78 | |||
79 | int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv) | ||
80 | { | ||
81 | int slot; | ||
82 | |||
83 | spin_lock_bh(&priv->tx.tx_lock); | ||
84 | slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM); | ||
85 | if (slot >= MAX_TX_BUF_NUM) { | ||
86 | spin_unlock_bh(&priv->tx.tx_lock); | ||
87 | return -ENOBUFS; | ||
88 | } | ||
89 | __set_bit(slot, priv->tx.tx_slot); | ||
90 | spin_unlock_bh(&priv->tx.tx_lock); | ||
91 | |||
92 | return slot; | ||
93 | } | ||
94 | |||
95 | void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot) | ||
96 | { | ||
97 | spin_lock_bh(&priv->tx.tx_lock); | ||
98 | __clear_bit(slot, priv->tx.tx_slot); | ||
99 | spin_unlock_bh(&priv->tx.tx_lock); | ||
100 | } | ||
101 | |||
102 | static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, | ||
103 | u16 qnum) | ||
104 | { | ||
105 | enum htc_endpoint_id epid; | ||
106 | |||
107 | switch (qnum) { | ||
108 | case 0: | ||
109 | TX_QSTAT_INC(WME_AC_VO); | ||
110 | epid = priv->data_vo_ep; | ||
111 | break; | ||
112 | case 1: | ||
113 | TX_QSTAT_INC(WME_AC_VI); | ||
114 | epid = priv->data_vi_ep; | ||
115 | break; | ||
116 | case 2: | ||
117 | TX_QSTAT_INC(WME_AC_BE); | ||
118 | epid = priv->data_be_ep; | ||
119 | break; | ||
120 | case 3: | ||
121 | default: | ||
122 | TX_QSTAT_INC(WME_AC_BK); | ||
123 | epid = priv->data_bk_ep; | ||
124 | break; | ||
125 | } | ||
126 | |||
127 | return epid; | ||
128 | } | ||
129 | |||
130 | static inline struct sk_buff_head* | ||
131 | get_htc_epid_queue(struct ath9k_htc_priv *priv, u8 epid) | ||
132 | { | ||
133 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
134 | struct sk_buff_head *epid_queue = NULL; | ||
135 | |||
136 | if (epid == priv->mgmt_ep) | ||
137 | epid_queue = &priv->tx.mgmt_ep_queue; | ||
138 | else if (epid == priv->cab_ep) | ||
139 | epid_queue = &priv->tx.cab_ep_queue; | ||
140 | else if (epid == priv->data_be_ep) | ||
141 | epid_queue = &priv->tx.data_be_queue; | ||
142 | else if (epid == priv->data_bk_ep) | ||
143 | epid_queue = &priv->tx.data_bk_queue; | ||
144 | else if (epid == priv->data_vi_ep) | ||
145 | epid_queue = &priv->tx.data_vi_queue; | ||
146 | else if (epid == priv->data_vo_ep) | ||
147 | epid_queue = &priv->tx.data_vo_queue; | ||
148 | else | ||
149 | ath_err(common, "Invalid EPID: %d\n", epid); | ||
150 | |||
151 | return epid_queue; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Removes the driver header and returns the TX slot number | ||
156 | */ | ||
157 | static inline int strip_drv_header(struct ath9k_htc_priv *priv, | ||
158 | struct sk_buff *skb) | ||
159 | { | ||
160 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
161 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
162 | int slot; | ||
163 | |||
164 | tx_ctl = HTC_SKB_CB(skb); | ||
165 | |||
166 | if (tx_ctl->epid == priv->mgmt_ep) { | ||
167 | struct tx_mgmt_hdr *tx_mhdr = | ||
168 | (struct tx_mgmt_hdr *)skb->data; | ||
169 | slot = tx_mhdr->cookie; | ||
170 | skb_pull(skb, sizeof(struct tx_mgmt_hdr)); | ||
171 | } else if ((tx_ctl->epid == priv->data_bk_ep) || | ||
172 | (tx_ctl->epid == priv->data_be_ep) || | ||
173 | (tx_ctl->epid == priv->data_vi_ep) || | ||
174 | (tx_ctl->epid == priv->data_vo_ep) || | ||
175 | (tx_ctl->epid == priv->cab_ep)) { | ||
176 | struct tx_frame_hdr *tx_fhdr = | ||
177 | (struct tx_frame_hdr *)skb->data; | ||
178 | slot = tx_fhdr->cookie; | ||
179 | skb_pull(skb, sizeof(struct tx_frame_hdr)); | ||
180 | } else { | ||
181 | ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid); | ||
182 | slot = -EINVAL; | ||
183 | } | ||
184 | |||
185 | return slot; | ||
186 | } | ||
187 | |||
56 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | 188 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, |
57 | struct ath9k_tx_queue_info *qinfo) | 189 | struct ath9k_tx_queue_info *qinfo) |
58 | { | 190 | { |
@@ -79,23 +211,140 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | |||
79 | return error; | 211 | return error; |
80 | } | 212 | } |
81 | 213 | ||
82 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | 214 | static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv, |
215 | struct ath9k_htc_vif *avp, | ||
216 | struct sk_buff *skb, | ||
217 | u8 sta_idx, u8 vif_idx, u8 slot) | ||
218 | { | ||
219 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
220 | struct ieee80211_mgmt *mgmt; | ||
221 | struct ieee80211_hdr *hdr; | ||
222 | struct tx_mgmt_hdr mgmt_hdr; | ||
223 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
224 | u8 *tx_fhdr; | ||
225 | |||
226 | tx_ctl = HTC_SKB_CB(skb); | ||
227 | hdr = (struct ieee80211_hdr *) skb->data; | ||
228 | |||
229 | memset(tx_ctl, 0, sizeof(*tx_ctl)); | ||
230 | memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); | ||
231 | |||
232 | /* | ||
233 | * Set the TSF adjust value for probe response | ||
234 | * frame also. | ||
235 | */ | ||
236 | if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) { | ||
237 | mgmt = (struct ieee80211_mgmt *)skb->data; | ||
238 | mgmt->u.probe_resp.timestamp = avp->tsfadjust; | ||
239 | } | ||
240 | |||
241 | tx_ctl->type = ATH9K_HTC_MGMT; | ||
242 | |||
243 | mgmt_hdr.node_idx = sta_idx; | ||
244 | mgmt_hdr.vif_idx = vif_idx; | ||
245 | mgmt_hdr.tidno = 0; | ||
246 | mgmt_hdr.flags = 0; | ||
247 | mgmt_hdr.cookie = slot; | ||
248 | |||
249 | mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | ||
250 | if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | ||
251 | mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
252 | else | ||
253 | mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
254 | |||
255 | tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); | ||
256 | memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); | ||
257 | tx_ctl->epid = priv->mgmt_ep; | ||
258 | } | ||
259 | |||
260 | static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv, | ||
261 | struct ieee80211_vif *vif, | ||
262 | struct sk_buff *skb, | ||
263 | u8 sta_idx, u8 vif_idx, u8 slot, | ||
264 | bool is_cab) | ||
265 | { | ||
266 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
267 | struct ieee80211_hdr *hdr; | ||
268 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
269 | struct tx_frame_hdr tx_hdr; | ||
270 | u32 flags = 0; | ||
271 | u8 *qc, *tx_fhdr; | ||
272 | u16 qnum; | ||
273 | |||
274 | tx_ctl = HTC_SKB_CB(skb); | ||
275 | hdr = (struct ieee80211_hdr *) skb->data; | ||
276 | |||
277 | memset(tx_ctl, 0, sizeof(*tx_ctl)); | ||
278 | memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); | ||
279 | |||
280 | tx_hdr.node_idx = sta_idx; | ||
281 | tx_hdr.vif_idx = vif_idx; | ||
282 | tx_hdr.cookie = slot; | ||
283 | |||
284 | /* | ||
285 | * This is a bit redundant but it helps to get | ||
286 | * the per-packet index quickly when draining the | ||
287 | * TX queue in the HIF layer. Otherwise we would | ||
288 | * have to parse the packet contents ... | ||
289 | */ | ||
290 | tx_ctl->sta_idx = sta_idx; | ||
291 | |||
292 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
293 | tx_ctl->type = ATH9K_HTC_AMPDU; | ||
294 | tx_hdr.data_type = ATH9K_HTC_AMPDU; | ||
295 | } else { | ||
296 | tx_ctl->type = ATH9K_HTC_NORMAL; | ||
297 | tx_hdr.data_type = ATH9K_HTC_NORMAL; | ||
298 | } | ||
299 | |||
300 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
301 | qc = ieee80211_get_qos_ctl(hdr); | ||
302 | tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
303 | } | ||
304 | |||
305 | /* Check for RTS protection */ | ||
306 | if (priv->hw->wiphy->rts_threshold != (u32) -1) | ||
307 | if (skb->len > priv->hw->wiphy->rts_threshold) | ||
308 | flags |= ATH9K_HTC_TX_RTSCTS; | ||
309 | |||
310 | /* CTS-to-self */ | ||
311 | if (!(flags & ATH9K_HTC_TX_RTSCTS) && | ||
312 | (vif && vif->bss_conf.use_cts_prot)) | ||
313 | flags |= ATH9K_HTC_TX_CTSONLY; | ||
314 | |||
315 | tx_hdr.flags = cpu_to_be32(flags); | ||
316 | tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | ||
317 | if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | ||
318 | tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
319 | else | ||
320 | tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
321 | |||
322 | tx_fhdr = skb_push(skb, sizeof(tx_hdr)); | ||
323 | memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); | ||
324 | |||
325 | if (is_cab) { | ||
326 | CAB_STAT_INC; | ||
327 | tx_ctl->epid = priv->cab_ep; | ||
328 | return; | ||
329 | } | ||
330 | |||
331 | qnum = skb_get_queue_mapping(skb); | ||
332 | tx_ctl->epid = get_htc_epid(priv, qnum); | ||
333 | } | ||
334 | |||
335 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, | ||
336 | struct sk_buff *skb, | ||
337 | u8 slot, bool is_cab) | ||
83 | { | 338 | { |
84 | struct ieee80211_hdr *hdr; | 339 | struct ieee80211_hdr *hdr; |
85 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 340 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
86 | struct ieee80211_sta *sta = tx_info->control.sta; | 341 | struct ieee80211_sta *sta = tx_info->control.sta; |
87 | struct ieee80211_vif *vif = tx_info->control.vif; | 342 | struct ieee80211_vif *vif = tx_info->control.vif; |
88 | struct ath9k_htc_sta *ista; | 343 | struct ath9k_htc_sta *ista; |
89 | struct ath9k_htc_vif *avp; | 344 | struct ath9k_htc_vif *avp = NULL; |
90 | struct ath9k_htc_tx_ctl tx_ctl; | ||
91 | enum htc_endpoint_id epid; | ||
92 | u16 qnum; | ||
93 | __le16 fc; | ||
94 | u8 *tx_fhdr; | ||
95 | u8 sta_idx, vif_idx; | 345 | u8 sta_idx, vif_idx; |
96 | 346 | ||
97 | hdr = (struct ieee80211_hdr *) skb->data; | 347 | hdr = (struct ieee80211_hdr *) skb->data; |
98 | fc = hdr->frame_control; | ||
99 | 348 | ||
100 | /* | 349 | /* |
101 | * Find out on which interface this packet has to be | 350 | * Find out on which interface this packet has to be |
@@ -124,218 +373,432 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | |||
124 | sta_idx = priv->vif_sta_pos[vif_idx]; | 373 | sta_idx = priv->vif_sta_pos[vif_idx]; |
125 | } | 374 | } |
126 | 375 | ||
127 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); | 376 | if (ieee80211_is_data(hdr->frame_control)) |
377 | ath9k_htc_tx_data(priv, vif, skb, | ||
378 | sta_idx, vif_idx, slot, is_cab); | ||
379 | else | ||
380 | ath9k_htc_tx_mgmt(priv, avp, skb, | ||
381 | sta_idx, vif_idx, slot); | ||
128 | 382 | ||
129 | if (ieee80211_is_data(fc)) { | ||
130 | struct tx_frame_hdr tx_hdr; | ||
131 | u32 flags = 0; | ||
132 | u8 *qc; | ||
133 | 383 | ||
134 | memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); | 384 | return htc_send(priv->htc, skb); |
385 | } | ||
135 | 386 | ||
136 | tx_hdr.node_idx = sta_idx; | 387 | static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, |
137 | tx_hdr.vif_idx = vif_idx; | 388 | struct ath9k_htc_sta *ista, u8 tid) |
389 | { | ||
390 | bool ret = false; | ||
138 | 391 | ||
139 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 392 | spin_lock_bh(&priv->tx.tx_lock); |
140 | tx_ctl.type = ATH9K_HTC_AMPDU; | 393 | if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) |
141 | tx_hdr.data_type = ATH9K_HTC_AMPDU; | 394 | ret = true; |
142 | } else { | 395 | spin_unlock_bh(&priv->tx.tx_lock); |
143 | tx_ctl.type = ATH9K_HTC_NORMAL; | 396 | |
144 | tx_hdr.data_type = ATH9K_HTC_NORMAL; | 397 | return ret; |
145 | } | 398 | } |
399 | |||
400 | static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, | ||
401 | struct ieee80211_vif *vif, | ||
402 | struct sk_buff *skb) | ||
403 | { | ||
404 | struct ieee80211_sta *sta; | ||
405 | struct ieee80211_hdr *hdr; | ||
406 | __le16 fc; | ||
407 | |||
408 | hdr = (struct ieee80211_hdr *) skb->data; | ||
409 | fc = hdr->frame_control; | ||
410 | |||
411 | rcu_read_lock(); | ||
412 | |||
413 | sta = ieee80211_find_sta(vif, hdr->addr1); | ||
414 | if (!sta) { | ||
415 | rcu_read_unlock(); | ||
416 | return; | ||
417 | } | ||
146 | 418 | ||
419 | if (sta && conf_is_ht(&priv->hw->conf) && | ||
420 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
147 | if (ieee80211_is_data_qos(fc)) { | 421 | if (ieee80211_is_data_qos(fc)) { |
422 | u8 *qc, tid; | ||
423 | struct ath9k_htc_sta *ista; | ||
424 | |||
148 | qc = ieee80211_get_qos_ctl(hdr); | 425 | qc = ieee80211_get_qos_ctl(hdr); |
149 | tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 426 | tid = qc[0] & 0xf; |
427 | ista = (struct ath9k_htc_sta *)sta->drv_priv; | ||
428 | if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) { | ||
429 | ieee80211_start_tx_ba_session(sta, tid, 0); | ||
430 | spin_lock_bh(&priv->tx.tx_lock); | ||
431 | ista->tid_state[tid] = AGGR_PROGRESS; | ||
432 | spin_unlock_bh(&priv->tx.tx_lock); | ||
433 | } | ||
150 | } | 434 | } |
435 | } | ||
151 | 436 | ||
152 | /* Check for RTS protection */ | 437 | rcu_read_unlock(); |
153 | if (priv->hw->wiphy->rts_threshold != (u32) -1) | 438 | } |
154 | if (skb->len > priv->hw->wiphy->rts_threshold) | ||
155 | flags |= ATH9K_HTC_TX_RTSCTS; | ||
156 | 439 | ||
157 | /* CTS-to-self */ | 440 | static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, |
158 | if (!(flags & ATH9K_HTC_TX_RTSCTS) && | 441 | struct sk_buff *skb, |
159 | (vif && vif->bss_conf.use_cts_prot)) | 442 | struct __wmi_event_txstatus *txs) |
160 | flags |= ATH9K_HTC_TX_CTSONLY; | 443 | { |
444 | struct ieee80211_vif *vif; | ||
445 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
446 | struct ieee80211_tx_info *tx_info; | ||
447 | struct ieee80211_tx_rate *rate; | ||
448 | struct ieee80211_conf *cur_conf = &priv->hw->conf; | ||
449 | struct ieee80211_supported_band *sband; | ||
450 | bool txok; | ||
451 | int slot; | ||
161 | 452 | ||
162 | tx_hdr.flags = cpu_to_be32(flags); | 453 | slot = strip_drv_header(priv, skb); |
163 | tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | 454 | if (slot < 0) { |
164 | if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | 455 | dev_kfree_skb_any(skb); |
165 | tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | 456 | return; |
166 | else | 457 | } |
167 | tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
168 | 458 | ||
169 | tx_fhdr = skb_push(skb, sizeof(tx_hdr)); | 459 | tx_ctl = HTC_SKB_CB(skb); |
170 | memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); | 460 | txok = tx_ctl->txok; |
461 | tx_info = IEEE80211_SKB_CB(skb); | ||
462 | vif = tx_info->control.vif; | ||
463 | rate = &tx_info->status.rates[0]; | ||
464 | sband = priv->hw->wiphy->bands[cur_conf->channel->band]; | ||
171 | 465 | ||
172 | qnum = skb_get_queue_mapping(skb); | 466 | memset(&tx_info->status, 0, sizeof(tx_info->status)); |
173 | 467 | ||
174 | switch (qnum) { | 468 | /* |
175 | case 0: | 469 | * URB submission failed for this frame, it never reached |
176 | TX_QSTAT_INC(WME_AC_VO); | 470 | * the target. |
177 | epid = priv->data_vo_ep; | 471 | */ |
178 | break; | 472 | if (!txok || !vif || !txs) |
179 | case 1: | 473 | goto send_mac80211; |
180 | TX_QSTAT_INC(WME_AC_VI); | ||
181 | epid = priv->data_vi_ep; | ||
182 | break; | ||
183 | case 2: | ||
184 | TX_QSTAT_INC(WME_AC_BE); | ||
185 | epid = priv->data_be_ep; | ||
186 | break; | ||
187 | case 3: | ||
188 | default: | ||
189 | TX_QSTAT_INC(WME_AC_BK); | ||
190 | epid = priv->data_bk_ep; | ||
191 | break; | ||
192 | } | ||
193 | } else { | ||
194 | struct tx_mgmt_hdr mgmt_hdr; | ||
195 | 474 | ||
196 | memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); | 475 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_ACK) |
476 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | ||
477 | |||
478 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_FILT) | ||
479 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
197 | 480 | ||
198 | tx_ctl.type = ATH9K_HTC_NORMAL; | 481 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_RTC_CTS) |
482 | rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; | ||
199 | 483 | ||
200 | mgmt_hdr.node_idx = sta_idx; | 484 | rate->count = 1; |
201 | mgmt_hdr.vif_idx = vif_idx; | 485 | rate->idx = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_RATE); |
202 | mgmt_hdr.tidno = 0; | ||
203 | mgmt_hdr.flags = 0; | ||
204 | 486 | ||
205 | mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | 487 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_MCS) { |
206 | if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | 488 | rate->flags |= IEEE80211_TX_RC_MCS; |
207 | mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
208 | else | ||
209 | mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
210 | 489 | ||
211 | tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); | 490 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_CW40) |
212 | memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); | 491 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; |
213 | epid = priv->mgmt_ep; | 492 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI) |
493 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | ||
494 | } else { | ||
495 | if (cur_conf->channel->band == IEEE80211_BAND_5GHZ) | ||
496 | rate->idx += 4; /* No CCK rates */ | ||
214 | } | 497 | } |
215 | 498 | ||
216 | return htc_send(priv->htc, skb, epid, &tx_ctl); | 499 | ath9k_htc_check_tx_aggr(priv, vif, skb); |
500 | |||
501 | send_mac80211: | ||
502 | spin_lock_bh(&priv->tx.tx_lock); | ||
503 | if (WARN_ON(--priv->tx.queued_cnt < 0)) | ||
504 | priv->tx.queued_cnt = 0; | ||
505 | spin_unlock_bh(&priv->tx.tx_lock); | ||
506 | |||
507 | ath9k_htc_tx_clear_slot(priv, slot); | ||
508 | |||
509 | /* Send status to mac80211 */ | ||
510 | ieee80211_tx_status(priv->hw, skb); | ||
217 | } | 511 | } |
218 | 512 | ||
219 | static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, | 513 | static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv, |
220 | struct ath9k_htc_sta *ista, u8 tid) | 514 | struct sk_buff_head *queue) |
221 | { | 515 | { |
222 | bool ret = false; | 516 | struct sk_buff *skb; |
223 | 517 | ||
224 | spin_lock_bh(&priv->tx_lock); | 518 | while ((skb = skb_dequeue(queue)) != NULL) { |
225 | if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) | 519 | ath9k_htc_tx_process(priv, skb, NULL); |
226 | ret = true; | 520 | } |
227 | spin_unlock_bh(&priv->tx_lock); | 521 | } |
228 | 522 | ||
229 | return ret; | 523 | void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) |
524 | { | ||
525 | struct ath9k_htc_tx_event *event, *tmp; | ||
526 | |||
527 | spin_lock_bh(&priv->tx.tx_lock); | ||
528 | priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN; | ||
529 | spin_unlock_bh(&priv->tx.tx_lock); | ||
530 | |||
531 | /* | ||
532 | * Ensure that all pending TX frames are flushed, | ||
533 | * and that the TX completion/failed tasklets is killed. | ||
534 | */ | ||
535 | htc_stop(priv->htc); | ||
536 | tasklet_kill(&priv->wmi->wmi_event_tasklet); | ||
537 | tasklet_kill(&priv->tx_failed_tasklet); | ||
538 | |||
539 | ath9k_htc_tx_drainq(priv, &priv->tx.mgmt_ep_queue); | ||
540 | ath9k_htc_tx_drainq(priv, &priv->tx.cab_ep_queue); | ||
541 | ath9k_htc_tx_drainq(priv, &priv->tx.data_be_queue); | ||
542 | ath9k_htc_tx_drainq(priv, &priv->tx.data_bk_queue); | ||
543 | ath9k_htc_tx_drainq(priv, &priv->tx.data_vi_queue); | ||
544 | ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue); | ||
545 | ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); | ||
546 | |||
547 | /* | ||
548 | * The TX cleanup timer has already been killed. | ||
549 | */ | ||
550 | spin_lock_bh(&priv->wmi->event_lock); | ||
551 | list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { | ||
552 | list_del(&event->list); | ||
553 | kfree(event); | ||
554 | } | ||
555 | spin_unlock_bh(&priv->wmi->event_lock); | ||
556 | |||
557 | spin_lock_bh(&priv->tx.tx_lock); | ||
558 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN; | ||
559 | spin_unlock_bh(&priv->tx.tx_lock); | ||
230 | } | 560 | } |
231 | 561 | ||
232 | void ath9k_tx_tasklet(unsigned long data) | 562 | void ath9k_tx_failed_tasklet(unsigned long data) |
233 | { | 563 | { |
234 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | 564 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; |
235 | struct ieee80211_vif *vif; | ||
236 | struct ieee80211_sta *sta; | ||
237 | struct ieee80211_hdr *hdr; | ||
238 | struct ieee80211_tx_info *tx_info; | ||
239 | struct sk_buff *skb = NULL; | ||
240 | __le16 fc; | ||
241 | 565 | ||
242 | while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) { | 566 | spin_lock_bh(&priv->tx.tx_lock); |
567 | if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { | ||
568 | spin_unlock_bh(&priv->tx.tx_lock); | ||
569 | return; | ||
570 | } | ||
571 | spin_unlock_bh(&priv->tx.tx_lock); | ||
243 | 572 | ||
244 | hdr = (struct ieee80211_hdr *) skb->data; | 573 | ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); |
245 | fc = hdr->frame_control; | 574 | } |
246 | tx_info = IEEE80211_SKB_CB(skb); | ||
247 | vif = tx_info->control.vif; | ||
248 | 575 | ||
249 | memset(&tx_info->status, 0, sizeof(tx_info->status)); | 576 | static inline bool check_cookie(struct ath9k_htc_priv *priv, |
577 | struct sk_buff *skb, | ||
578 | u8 cookie, u8 epid) | ||
579 | { | ||
580 | u8 fcookie = 0; | ||
581 | |||
582 | if (epid == priv->mgmt_ep) { | ||
583 | struct tx_mgmt_hdr *hdr; | ||
584 | hdr = (struct tx_mgmt_hdr *) skb->data; | ||
585 | fcookie = hdr->cookie; | ||
586 | } else if ((epid == priv->data_bk_ep) || | ||
587 | (epid == priv->data_be_ep) || | ||
588 | (epid == priv->data_vi_ep) || | ||
589 | (epid == priv->data_vo_ep) || | ||
590 | (epid == priv->cab_ep)) { | ||
591 | struct tx_frame_hdr *hdr; | ||
592 | hdr = (struct tx_frame_hdr *) skb->data; | ||
593 | fcookie = hdr->cookie; | ||
594 | } | ||
250 | 595 | ||
251 | if (!vif) | 596 | if (fcookie == cookie) |
252 | goto send_mac80211; | 597 | return true; |
253 | 598 | ||
254 | rcu_read_lock(); | 599 | return false; |
600 | } | ||
255 | 601 | ||
256 | sta = ieee80211_find_sta(vif, hdr->addr1); | 602 | static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv, |
257 | if (!sta) { | 603 | struct __wmi_event_txstatus *txs) |
258 | rcu_read_unlock(); | 604 | { |
259 | ieee80211_tx_status(priv->hw, skb); | 605 | struct ath_common *common = ath9k_hw_common(priv->ah); |
260 | continue; | 606 | struct sk_buff_head *epid_queue; |
607 | struct sk_buff *skb, *tmp; | ||
608 | unsigned long flags; | ||
609 | u8 epid = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_EPID); | ||
610 | |||
611 | epid_queue = get_htc_epid_queue(priv, epid); | ||
612 | if (!epid_queue) | ||
613 | return NULL; | ||
614 | |||
615 | spin_lock_irqsave(&epid_queue->lock, flags); | ||
616 | skb_queue_walk_safe(epid_queue, skb, tmp) { | ||
617 | if (check_cookie(priv, skb, txs->cookie, epid)) { | ||
618 | __skb_unlink(skb, epid_queue); | ||
619 | spin_unlock_irqrestore(&epid_queue->lock, flags); | ||
620 | return skb; | ||
261 | } | 621 | } |
622 | } | ||
623 | spin_unlock_irqrestore(&epid_queue->lock, flags); | ||
262 | 624 | ||
263 | /* Check if we need to start aggregation */ | 625 | ath_dbg(common, ATH_DBG_XMIT, |
626 | "No matching packet for cookie: %d, epid: %d\n", | ||
627 | txs->cookie, epid); | ||
264 | 628 | ||
265 | if (sta && conf_is_ht(&priv->hw->conf) && | 629 | return NULL; |
266 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | 630 | } |
267 | if (ieee80211_is_data_qos(fc)) { | ||
268 | u8 *qc, tid; | ||
269 | struct ath9k_htc_sta *ista; | ||
270 | 631 | ||
271 | qc = ieee80211_get_qos_ctl(hdr); | 632 | void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) |
272 | tid = qc[0] & 0xf; | 633 | { |
273 | ista = (struct ath9k_htc_sta *)sta->drv_priv; | 634 | struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event; |
635 | struct __wmi_event_txstatus *__txs; | ||
636 | struct sk_buff *skb; | ||
637 | struct ath9k_htc_tx_event *tx_pend; | ||
638 | int i; | ||
274 | 639 | ||
275 | if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { | 640 | for (i = 0; i < txs->cnt; i++) { |
276 | ieee80211_start_tx_ba_session(sta, tid, 0); | 641 | WARN_ON(txs->cnt > HTC_MAX_TX_STATUS); |
277 | spin_lock_bh(&priv->tx_lock); | ||
278 | ista->tid_state[tid] = AGGR_PROGRESS; | ||
279 | spin_unlock_bh(&priv->tx_lock); | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | 642 | ||
284 | rcu_read_unlock(); | 643 | __txs = &txs->txstatus[i]; |
644 | |||
645 | skb = ath9k_htc_tx_get_packet(priv, __txs); | ||
646 | if (!skb) { | ||
647 | /* | ||
648 | * Store this event, so that the TX cleanup | ||
649 | * routine can check later for the needed packet. | ||
650 | */ | ||
651 | tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event), | ||
652 | GFP_ATOMIC); | ||
653 | if (!tx_pend) | ||
654 | continue; | ||
655 | |||
656 | memcpy(&tx_pend->txs, __txs, | ||
657 | sizeof(struct __wmi_event_txstatus)); | ||
658 | |||
659 | spin_lock(&priv->wmi->event_lock); | ||
660 | list_add_tail(&tx_pend->list, | ||
661 | &priv->wmi->pending_tx_events); | ||
662 | spin_unlock(&priv->wmi->event_lock); | ||
285 | 663 | ||
286 | send_mac80211: | 664 | continue; |
287 | /* Send status to mac80211 */ | 665 | } |
288 | ieee80211_tx_status(priv->hw, skb); | 666 | |
667 | ath9k_htc_tx_process(priv, skb, __txs); | ||
289 | } | 668 | } |
290 | 669 | ||
291 | /* Wake TX queues if needed */ | 670 | /* Wake TX queues if needed */ |
292 | spin_lock_bh(&priv->tx_lock); | 671 | ath9k_htc_check_wake_queues(priv); |
293 | if (priv->tx_queues_stop) { | ||
294 | priv->tx_queues_stop = false; | ||
295 | spin_unlock_bh(&priv->tx_lock); | ||
296 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
297 | "Waking up TX queues\n"); | ||
298 | ieee80211_wake_queues(priv->hw); | ||
299 | return; | ||
300 | } | ||
301 | spin_unlock_bh(&priv->tx_lock); | ||
302 | } | 672 | } |
303 | 673 | ||
304 | void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, | 674 | void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, |
305 | enum htc_endpoint_id ep_id, bool txok) | 675 | enum htc_endpoint_id ep_id, bool txok) |
306 | { | 676 | { |
307 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; | 677 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; |
308 | struct ath_common *common = ath9k_hw_common(priv->ah); | 678 | struct ath9k_htc_tx_ctl *tx_ctl; |
309 | struct ieee80211_tx_info *tx_info; | 679 | struct sk_buff_head *epid_queue; |
310 | 680 | ||
311 | if (!skb) | 681 | tx_ctl = HTC_SKB_CB(skb); |
682 | tx_ctl->txok = txok; | ||
683 | tx_ctl->timestamp = jiffies; | ||
684 | |||
685 | if (!txok) { | ||
686 | skb_queue_tail(&priv->tx.tx_failed, skb); | ||
687 | tasklet_schedule(&priv->tx_failed_tasklet); | ||
312 | return; | 688 | return; |
689 | } | ||
313 | 690 | ||
314 | if (ep_id == priv->mgmt_ep) { | 691 | epid_queue = get_htc_epid_queue(priv, ep_id); |
315 | skb_pull(skb, sizeof(struct tx_mgmt_hdr)); | 692 | if (!epid_queue) { |
316 | } else if ((ep_id == priv->data_bk_ep) || | ||
317 | (ep_id == priv->data_be_ep) || | ||
318 | (ep_id == priv->data_vi_ep) || | ||
319 | (ep_id == priv->data_vo_ep)) { | ||
320 | skb_pull(skb, sizeof(struct tx_frame_hdr)); | ||
321 | } else { | ||
322 | ath_err(common, "Unsupported TX EPID: %d\n", ep_id); | ||
323 | dev_kfree_skb_any(skb); | 693 | dev_kfree_skb_any(skb); |
324 | return; | 694 | return; |
325 | } | 695 | } |
326 | 696 | ||
327 | tx_info = IEEE80211_SKB_CB(skb); | 697 | skb_queue_tail(epid_queue, skb); |
698 | } | ||
328 | 699 | ||
329 | if (txok) | 700 | static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb) |
330 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 701 | { |
702 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
703 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
331 | 704 | ||
332 | skb_queue_tail(&priv->tx_queue, skb); | 705 | tx_ctl = HTC_SKB_CB(skb); |
333 | tasklet_schedule(&priv->tx_tasklet); | 706 | |
707 | if (time_after(jiffies, | ||
708 | tx_ctl->timestamp + | ||
709 | msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) { | ||
710 | ath_dbg(common, ATH_DBG_XMIT, | ||
711 | "Dropping a packet due to TX timeout\n"); | ||
712 | return true; | ||
713 | } | ||
714 | |||
715 | return false; | ||
716 | } | ||
717 | |||
718 | static void ath9k_htc_tx_cleanup_queue(struct ath9k_htc_priv *priv, | ||
719 | struct sk_buff_head *epid_queue) | ||
720 | { | ||
721 | bool process = false; | ||
722 | unsigned long flags; | ||
723 | struct sk_buff *skb, *tmp; | ||
724 | struct sk_buff_head queue; | ||
725 | |||
726 | skb_queue_head_init(&queue); | ||
727 | |||
728 | spin_lock_irqsave(&epid_queue->lock, flags); | ||
729 | skb_queue_walk_safe(epid_queue, skb, tmp) { | ||
730 | if (check_packet(priv, skb)) { | ||
731 | __skb_unlink(skb, epid_queue); | ||
732 | __skb_queue_tail(&queue, skb); | ||
733 | process = true; | ||
734 | } | ||
735 | } | ||
736 | spin_unlock_irqrestore(&epid_queue->lock, flags); | ||
737 | |||
738 | if (process) { | ||
739 | skb_queue_walk_safe(&queue, skb, tmp) { | ||
740 | __skb_unlink(skb, &queue); | ||
741 | ath9k_htc_tx_process(priv, skb, NULL); | ||
742 | } | ||
743 | } | ||
744 | } | ||
745 | |||
746 | void ath9k_htc_tx_cleanup_timer(unsigned long data) | ||
747 | { | ||
748 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) data; | ||
749 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
750 | struct ath9k_htc_tx_event *event, *tmp; | ||
751 | struct sk_buff *skb; | ||
752 | |||
753 | spin_lock(&priv->wmi->event_lock); | ||
754 | list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { | ||
755 | |||
756 | skb = ath9k_htc_tx_get_packet(priv, &event->txs); | ||
757 | if (skb) { | ||
758 | ath_dbg(common, ATH_DBG_XMIT, | ||
759 | "Found packet for cookie: %d, epid: %d\n", | ||
760 | event->txs.cookie, | ||
761 | MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID)); | ||
762 | |||
763 | ath9k_htc_tx_process(priv, skb, &event->txs); | ||
764 | list_del(&event->list); | ||
765 | kfree(event); | ||
766 | continue; | ||
767 | } | ||
768 | |||
769 | if (++event->count >= ATH9K_HTC_TX_TIMEOUT_COUNT) { | ||
770 | list_del(&event->list); | ||
771 | kfree(event); | ||
772 | } | ||
773 | } | ||
774 | spin_unlock(&priv->wmi->event_lock); | ||
775 | |||
776 | /* | ||
777 | * Check if status-pending packets have to be cleaned up. | ||
778 | */ | ||
779 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.mgmt_ep_queue); | ||
780 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.cab_ep_queue); | ||
781 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_be_queue); | ||
782 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_bk_queue); | ||
783 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vi_queue); | ||
784 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vo_queue); | ||
785 | |||
786 | /* Wake TX queues if needed */ | ||
787 | ath9k_htc_check_wake_queues(priv); | ||
788 | |||
789 | mod_timer(&priv->tx.cleanup_timer, | ||
790 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
334 | } | 791 | } |
335 | 792 | ||
336 | int ath9k_tx_init(struct ath9k_htc_priv *priv) | 793 | int ath9k_tx_init(struct ath9k_htc_priv *priv) |
337 | { | 794 | { |
338 | skb_queue_head_init(&priv->tx_queue); | 795 | skb_queue_head_init(&priv->tx.mgmt_ep_queue); |
796 | skb_queue_head_init(&priv->tx.cab_ep_queue); | ||
797 | skb_queue_head_init(&priv->tx.data_be_queue); | ||
798 | skb_queue_head_init(&priv->tx.data_bk_queue); | ||
799 | skb_queue_head_init(&priv->tx.data_vi_queue); | ||
800 | skb_queue_head_init(&priv->tx.data_vo_queue); | ||
801 | skb_queue_head_init(&priv->tx.tx_failed); | ||
339 | return 0; | 802 | return 0; |
340 | } | 803 | } |
341 | 804 | ||
@@ -507,8 +970,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
507 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | 970 | int last_rssi = ATH_RSSI_DUMMY_MARKER; |
508 | __le16 fc; | 971 | __le16 fc; |
509 | 972 | ||
510 | if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { | 973 | if (skb->len < HTC_RX_FRAME_HEADER_SIZE) { |
511 | ath_err(common, "Corrupted RX frame, dropping\n"); | 974 | ath_err(common, "Corrupted RX frame, dropping (len: %d)\n", |
975 | skb->len); | ||
512 | goto rx_next; | 976 | goto rx_next; |
513 | } | 977 | } |
514 | 978 | ||
@@ -522,6 +986,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
522 | goto rx_next; | 986 | goto rx_next; |
523 | } | 987 | } |
524 | 988 | ||
989 | ath9k_htc_err_stat_rx(priv, rxstatus); | ||
990 | |||
525 | /* Get the RX status information */ | 991 | /* Get the RX status information */ |
526 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); | 992 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); |
527 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); | 993 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index c41ab8c30161..5c76352b1319 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, | 19 | static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, |
20 | u16 len, u8 flags, u8 epid, | 20 | u16 len, u8 flags, u8 epid) |
21 | struct ath9k_htc_tx_ctl *tx_ctl) | 21 | |
22 | { | 22 | { |
23 | struct htc_frame_hdr *hdr; | 23 | struct htc_frame_hdr *hdr; |
24 | struct htc_endpoint *endpoint = &target->endpoint[epid]; | 24 | struct htc_endpoint *endpoint = &target->endpoint[epid]; |
@@ -30,8 +30,8 @@ static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, | |||
30 | hdr->flags = flags; | 30 | hdr->flags = flags; |
31 | hdr->payload_len = cpu_to_be16(len); | 31 | hdr->payload_len = cpu_to_be16(len); |
32 | 32 | ||
33 | status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb, | 33 | status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb); |
34 | tx_ctl); | 34 | |
35 | return status; | 35 | return status; |
36 | } | 36 | } |
37 | 37 | ||
@@ -162,7 +162,7 @@ static int htc_config_pipe_credits(struct htc_target *target) | |||
162 | 162 | ||
163 | target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; | 163 | target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; |
164 | 164 | ||
165 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | 165 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); |
166 | if (ret) | 166 | if (ret) |
167 | goto err; | 167 | goto err; |
168 | 168 | ||
@@ -197,7 +197,7 @@ static int htc_setup_complete(struct htc_target *target) | |||
197 | 197 | ||
198 | target->htc_flags |= HTC_OP_START_WAIT; | 198 | target->htc_flags |= HTC_OP_START_WAIT; |
199 | 199 | ||
200 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | 200 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); |
201 | if (ret) | 201 | if (ret) |
202 | goto err; | 202 | goto err; |
203 | 203 | ||
@@ -268,7 +268,7 @@ int htc_connect_service(struct htc_target *target, | |||
268 | conn_msg->dl_pipeid = endpoint->dl_pipeid; | 268 | conn_msg->dl_pipeid = endpoint->dl_pipeid; |
269 | conn_msg->ul_pipeid = endpoint->ul_pipeid; | 269 | conn_msg->ul_pipeid = endpoint->ul_pipeid; |
270 | 270 | ||
271 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | 271 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); |
272 | if (ret) | 272 | if (ret) |
273 | goto err; | 273 | goto err; |
274 | 274 | ||
@@ -286,35 +286,33 @@ err: | |||
286 | return ret; | 286 | return ret; |
287 | } | 287 | } |
288 | 288 | ||
289 | int htc_send(struct htc_target *target, struct sk_buff *skb, | 289 | int htc_send(struct htc_target *target, struct sk_buff *skb) |
290 | enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl) | ||
291 | { | 290 | { |
292 | return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl); | 291 | struct ath9k_htc_tx_ctl *tx_ctl; |
292 | |||
293 | tx_ctl = HTC_SKB_CB(skb); | ||
294 | return htc_issue_send(target, skb, skb->len, 0, tx_ctl->epid); | ||
293 | } | 295 | } |
294 | 296 | ||
295 | void htc_stop(struct htc_target *target) | 297 | int htc_send_epid(struct htc_target *target, struct sk_buff *skb, |
298 | enum htc_endpoint_id epid) | ||
296 | { | 299 | { |
297 | enum htc_endpoint_id epid; | 300 | return htc_issue_send(target, skb, skb->len, 0, epid); |
298 | struct htc_endpoint *endpoint; | 301 | } |
299 | 302 | ||
300 | for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { | 303 | void htc_stop(struct htc_target *target) |
301 | endpoint = &target->endpoint[epid]; | 304 | { |
302 | if (endpoint->service_id != 0) | 305 | target->hif->stop(target->hif_dev); |
303 | target->hif->stop(target->hif_dev, endpoint->ul_pipeid); | ||
304 | } | ||
305 | } | 306 | } |
306 | 307 | ||
307 | void htc_start(struct htc_target *target) | 308 | void htc_start(struct htc_target *target) |
308 | { | 309 | { |
309 | enum htc_endpoint_id epid; | 310 | target->hif->start(target->hif_dev); |
310 | struct htc_endpoint *endpoint; | 311 | } |
311 | 312 | ||
312 | for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { | 313 | void htc_sta_drain(struct htc_target *target, u8 idx) |
313 | endpoint = &target->endpoint[epid]; | 314 | { |
314 | if (endpoint->service_id != 0) | 315 | target->hif->sta_drain(target->hif_dev, idx); |
315 | target->hif->start(target->hif_dev, | ||
316 | endpoint->ul_pipeid); | ||
317 | } | ||
318 | } | 316 | } |
319 | 317 | ||
320 | void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, | 318 | void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index ecd018798c47..cb9174ade53e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h | |||
@@ -33,10 +33,10 @@ struct ath9k_htc_hif { | |||
33 | u8 control_dl_pipe; | 33 | u8 control_dl_pipe; |
34 | u8 control_ul_pipe; | 34 | u8 control_ul_pipe; |
35 | 35 | ||
36 | void (*start) (void *hif_handle, u8 pipe); | 36 | void (*start) (void *hif_handle); |
37 | void (*stop) (void *hif_handle, u8 pipe); | 37 | void (*stop) (void *hif_handle); |
38 | int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf, | 38 | void (*sta_drain) (void *hif_handle, u8 idx); |
39 | struct ath9k_htc_tx_ctl *tx_ctl); | 39 | int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf); |
40 | }; | 40 | }; |
41 | 41 | ||
42 | enum htc_endpoint_id { | 42 | enum htc_endpoint_id { |
@@ -205,10 +205,12 @@ int htc_init(struct htc_target *target); | |||
205 | int htc_connect_service(struct htc_target *target, | 205 | int htc_connect_service(struct htc_target *target, |
206 | struct htc_service_connreq *service_connreq, | 206 | struct htc_service_connreq *service_connreq, |
207 | enum htc_endpoint_id *conn_rsp_eid); | 207 | enum htc_endpoint_id *conn_rsp_eid); |
208 | int htc_send(struct htc_target *target, struct sk_buff *skb, | 208 | int htc_send(struct htc_target *target, struct sk_buff *skb); |
209 | enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl); | 209 | int htc_send_epid(struct htc_target *target, struct sk_buff *skb, |
210 | enum htc_endpoint_id epid); | ||
210 | void htc_stop(struct htc_target *target); | 211 | void htc_stop(struct htc_target *target); |
211 | void htc_start(struct htc_target *target); | 212 | void htc_start(struct htc_target *target); |
213 | void htc_sta_drain(struct htc_target *target, u8 idx); | ||
212 | 214 | ||
213 | void ath9k_htc_rx_msg(struct htc_target *htc_handle, | 215 | void ath9k_htc_rx_msg(struct htc_target *htc_handle, |
214 | struct sk_buff *skb, u32 len, u8 pipe_id); | 216 | struct sk_buff *skb, u32 len, u8 pipe_id); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1b5bd13b0a6c..3a8c41c782e9 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -676,42 +676,55 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | |||
676 | } | 676 | } |
677 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); | 677 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); |
678 | 678 | ||
679 | #define DPLL2_KD_VAL 0x3D | 679 | #define DPLL3_PHASE_SHIFT_VAL 0x1 |
680 | #define DPLL2_KI_VAL 0x06 | ||
681 | #define DPLL3_PHASE_SHIFT_VAL 0x1 | ||
682 | |||
683 | static void ath9k_hw_init_pll(struct ath_hw *ah, | 680 | static void ath9k_hw_init_pll(struct ath_hw *ah, |
684 | struct ath9k_channel *chan) | 681 | struct ath9k_channel *chan) |
685 | { | 682 | { |
686 | u32 pll; | 683 | u32 pll; |
687 | 684 | ||
688 | if (AR_SREV_9485(ah)) { | 685 | if (AR_SREV_9485(ah)) { |
689 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | ||
690 | REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01); | ||
691 | |||
692 | REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, | ||
693 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | ||
694 | 686 | ||
695 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | 687 | /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */ |
696 | udelay(1000); | 688 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
689 | AR_CH0_BB_DPLL2_PLL_PWD, 0x1); | ||
690 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
691 | AR_CH0_DPLL2_KD, 0x40); | ||
692 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
693 | AR_CH0_DPLL2_KI, 0x4); | ||
697 | 694 | ||
698 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | 695 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, |
696 | AR_CH0_BB_DPLL1_REFDIV, 0x5); | ||
697 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, | ||
698 | AR_CH0_BB_DPLL1_NINI, 0x58); | ||
699 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, | ||
700 | AR_CH0_BB_DPLL1_NFRAC, 0x0); | ||
699 | 701 | ||
700 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 702 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
701 | AR_CH0_DPLL2_KD, DPLL2_KD_VAL); | 703 | AR_CH0_BB_DPLL2_OUTDIV, 0x1); |
704 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
705 | AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1); | ||
702 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 706 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
703 | AR_CH0_DPLL2_KI, DPLL2_KI_VAL); | 707 | AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1); |
704 | 708 | ||
709 | /* program BB PLL phase_shift to 0x6 */ | ||
705 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | 710 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, |
706 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | 711 | AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6); |
707 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); | 712 | |
713 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
714 | AR_CH0_BB_DPLL2_PLL_PWD, 0x0); | ||
708 | udelay(1000); | 715 | udelay(1000); |
716 | |||
717 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | ||
718 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | ||
709 | } | 719 | } |
710 | 720 | ||
711 | pll = ath9k_hw_compute_pll_control(ah, chan); | 721 | pll = ath9k_hw_compute_pll_control(ah, chan); |
712 | 722 | ||
713 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 723 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
714 | 724 | ||
725 | if (AR_SREV_9485(ah)) | ||
726 | udelay(1000); | ||
727 | |||
715 | /* Switch the core clock for ar9271 to 117Mhz */ | 728 | /* Switch the core clock for ar9271 to 117Mhz */ |
716 | if (AR_SREV_9271(ah)) { | 729 | if (AR_SREV_9271(ah)) { |
717 | udelay(500); | 730 | udelay(500); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a778b66f4438..073bc9e1c792 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -846,6 +846,14 @@ struct ath_hw { | |||
846 | u32 ent_mode; | 846 | u32 ent_mode; |
847 | }; | 847 | }; |
848 | 848 | ||
849 | struct ath_bus_ops { | ||
850 | enum ath_bus_type ath_bus_type; | ||
851 | void (*read_cachesize)(struct ath_common *common, int *csz); | ||
852 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | ||
853 | void (*bt_coex_prep)(struct ath_common *common); | ||
854 | void (*extn_synch_en)(struct ath_common *common); | ||
855 | }; | ||
856 | |||
849 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) | 857 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) |
850 | { | 858 | { |
851 | return &ah->common; | 859 | return &ah->common; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ba1c9a684eff..a55a8929810b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1375,6 +1375,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1375 | if ((iter_data.naps + iter_data.nadhocs) > 0) { | 1375 | if ((iter_data.naps + iter_data.nadhocs) > 0) { |
1376 | sc->sc_flags |= SC_OP_ANI_RUN; | 1376 | sc->sc_flags |= SC_OP_ANI_RUN; |
1377 | ath_start_ani(common); | 1377 | ath_start_ani(common); |
1378 | } else { | ||
1379 | sc->sc_flags &= ~SC_OP_ANI_RUN; | ||
1380 | del_timer_sync(&common->ani.timer); | ||
1378 | } | 1381 | } |
1379 | } | 1382 | } |
1380 | 1383 | ||
@@ -2201,6 +2204,21 @@ out: | |||
2201 | ath9k_ps_restore(sc); | 2204 | ath9k_ps_restore(sc); |
2202 | } | 2205 | } |
2203 | 2206 | ||
2207 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) | ||
2208 | { | ||
2209 | struct ath_softc *sc = hw->priv; | ||
2210 | int i; | ||
2211 | |||
2212 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
2213 | if (!ATH_TXQ_SETUP(sc, i)) | ||
2214 | continue; | ||
2215 | |||
2216 | if (ath9k_has_pending_frames(sc, &sc->tx.txq[i])) | ||
2217 | return true; | ||
2218 | } | ||
2219 | return false; | ||
2220 | } | ||
2221 | |||
2204 | struct ieee80211_ops ath9k_ops = { | 2222 | struct ieee80211_ops ath9k_ops = { |
2205 | .tx = ath9k_tx, | 2223 | .tx = ath9k_tx, |
2206 | .start = ath9k_start, | 2224 | .start = ath9k_start, |
@@ -2223,4 +2241,5 @@ struct ieee80211_ops ath9k_ops = { | |||
2223 | .rfkill_poll = ath9k_rfkill_poll_state, | 2241 | .rfkill_poll = ath9k_rfkill_poll_state, |
2224 | .set_coverage_class = ath9k_set_coverage_class, | 2242 | .set_coverage_class = ath9k_set_coverage_class, |
2225 | .flush = ath9k_flush, | 2243 | .flush = ath9k_flush, |
2244 | .tx_frames_pending = ath9k_tx_frames_pending, | ||
2226 | }; | 2245 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index f50e2c29f71e..8e5fe9d7f174 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | #define CHANSEL_DIV 15 | 20 | #define CHANSEL_DIV 15 |
21 | #define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) | 21 | #define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) |
22 | #define CHANSEL_2G_9485(_freq) ((((_freq) * 0x10000) - 215) / CHANSEL_DIV) | ||
23 | #define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) | 22 | #define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) |
24 | 23 | ||
25 | #define AR_PHY_BASE 0x9800 | 24 | #define AR_PHY_BASE 0x9800 |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index a3241cd089b1..2a40532126f3 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1092,8 +1092,7 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, | |||
1092 | if (!(rate->flags & IEEE80211_TX_RC_MCS)) | 1092 | if (!(rate->flags & IEEE80211_TX_RC_MCS)) |
1093 | return rate->idx; | 1093 | return rate->idx; |
1094 | 1094 | ||
1095 | while (rate->idx > mcs_rix_off[i] && | 1095 | while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) { |
1096 | i < ARRAY_SIZE(mcs_rix_off)) { | ||
1097 | rix++; i++; | 1096 | rix++; i++; |
1098 | } | 1097 | } |
1099 | 1098 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 3842b7518661..b81bfc4d66ef 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -75,7 +75,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) | |||
75 | *sc->rx.rxlink = bf->bf_daddr; | 75 | *sc->rx.rxlink = bf->bf_daddr; |
76 | 76 | ||
77 | sc->rx.rxlink = &ds->ds_link; | 77 | sc->rx.rxlink = &ds->ds_link; |
78 | ath9k_hw_rxena(ah); | ||
79 | } | 78 | } |
80 | 79 | ||
81 | static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) | 80 | static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) |
@@ -426,9 +425,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
426 | else | 425 | else |
427 | rfilt |= ATH9K_RX_FILTER_BEACON; | 426 | rfilt |= ATH9K_RX_FILTER_BEACON; |
428 | 427 | ||
429 | if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) || | 428 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
430 | AR_SREV_9285_12_OR_LATER(sc->sc_ah)) && | ||
431 | (sc->sc_ah->opmode == NL80211_IFTYPE_AP) && | ||
432 | (sc->rx.rxfilter & FIF_PSPOLL)) | 429 | (sc->rx.rxfilter & FIF_PSPOLL)) |
433 | rfilt |= ATH9K_RX_FILTER_PSPOLL; | 430 | rfilt |= ATH9K_RX_FILTER_PSPOLL; |
434 | 431 | ||
@@ -1767,6 +1764,7 @@ requeue: | |||
1767 | } else { | 1764 | } else { |
1768 | list_move_tail(&bf->list, &sc->rx.rxbuf); | 1765 | list_move_tail(&bf->list, &sc->rx.rxbuf); |
1769 | ath_rx_buf_link(sc, bf); | 1766 | ath_rx_buf_link(sc, bf); |
1767 | ath9k_hw_rxena(ah); | ||
1770 | } | 1768 | } |
1771 | } while (1); | 1769 | } while (1); |
1772 | 1770 | ||
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 693d543937b5..6acbf0e2240b 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -858,9 +858,7 @@ | |||
858 | #define AR_SREV_9300(_ah) \ | 858 | #define AR_SREV_9300(_ah) \ |
859 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) | 859 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) |
860 | #define AR_SREV_9300_20_OR_LATER(_ah) \ | 860 | #define AR_SREV_9300_20_OR_LATER(_ah) \ |
861 | (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ | 861 | ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) |
862 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ | ||
863 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20))) | ||
864 | 862 | ||
865 | #define AR_SREV_9485(_ah) \ | 863 | #define AR_SREV_9485(_ah) \ |
866 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) | 864 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) |
@@ -1088,14 +1086,35 @@ enum { | |||
1088 | #define AR_ENT_OTP 0x40d8 | 1086 | #define AR_ENT_OTP 0x40d8 |
1089 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 | 1087 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 |
1090 | #define AR_ENT_OTP_MPSD 0x00800000 | 1088 | #define AR_ENT_OTP_MPSD 0x00800000 |
1091 | #define AR_CH0_BB_DPLL2 0x16184 | 1089 | |
1090 | #define AR_CH0_BB_DPLL1 0x16180 | ||
1091 | #define AR_CH0_BB_DPLL1_REFDIV 0xF8000000 | ||
1092 | #define AR_CH0_BB_DPLL1_REFDIV_S 27 | ||
1093 | #define AR_CH0_BB_DPLL1_NINI 0x07FC0000 | ||
1094 | #define AR_CH0_BB_DPLL1_NINI_S 18 | ||
1095 | #define AR_CH0_BB_DPLL1_NFRAC 0x0003FFFF | ||
1096 | #define AR_CH0_BB_DPLL1_NFRAC_S 0 | ||
1097 | |||
1098 | #define AR_CH0_BB_DPLL2 0x16184 | ||
1099 | #define AR_CH0_BB_DPLL2_LOCAL_PLL 0x40000000 | ||
1100 | #define AR_CH0_BB_DPLL2_LOCAL_PLL_S 30 | ||
1101 | #define AR_CH0_DPLL2_KI 0x3C000000 | ||
1102 | #define AR_CH0_DPLL2_KI_S 26 | ||
1103 | #define AR_CH0_DPLL2_KD 0x03F80000 | ||
1104 | #define AR_CH0_DPLL2_KD_S 19 | ||
1105 | #define AR_CH0_BB_DPLL2_EN_NEGTRIG 0x00040000 | ||
1106 | #define AR_CH0_BB_DPLL2_EN_NEGTRIG_S 18 | ||
1107 | #define AR_CH0_BB_DPLL2_PLL_PWD 0x00010000 | ||
1108 | #define AR_CH0_BB_DPLL2_PLL_PWD_S 16 | ||
1109 | #define AR_CH0_BB_DPLL2_OUTDIV 0x0000E000 | ||
1110 | #define AR_CH0_BB_DPLL2_OUTDIV_S 13 | ||
1111 | |||
1092 | #define AR_CH0_BB_DPLL3 0x16188 | 1112 | #define AR_CH0_BB_DPLL3 0x16188 |
1113 | #define AR_CH0_BB_DPLL3_PHASE_SHIFT 0x3F800000 | ||
1114 | #define AR_CH0_BB_DPLL3_PHASE_SHIFT_S 23 | ||
1115 | |||
1093 | #define AR_CH0_DDR_DPLL2 0x16244 | 1116 | #define AR_CH0_DDR_DPLL2 0x16244 |
1094 | #define AR_CH0_DDR_DPLL3 0x16248 | 1117 | #define AR_CH0_DDR_DPLL3 0x16248 |
1095 | #define AR_CH0_DPLL2_KD 0x03F80000 | ||
1096 | #define AR_CH0_DPLL2_KD_S 19 | ||
1097 | #define AR_CH0_DPLL2_KI 0x3C000000 | ||
1098 | #define AR_CH0_DPLL2_KI_S 26 | ||
1099 | #define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 | 1118 | #define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 |
1100 | #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 | 1119 | #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 |
1101 | #define AR_PHY_CCA_NOM_VAL_2GHZ -118 | 1120 | #define AR_PHY_CCA_NOM_VAL_2GHZ -118 |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index d3d24904f62f..8f095ad0a3db 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -23,20 +23,18 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
23 | return "WMI_ECHO_CMDID"; | 23 | return "WMI_ECHO_CMDID"; |
24 | case WMI_ACCESS_MEMORY_CMDID: | 24 | case WMI_ACCESS_MEMORY_CMDID: |
25 | return "WMI_ACCESS_MEMORY_CMDID"; | 25 | return "WMI_ACCESS_MEMORY_CMDID"; |
26 | case WMI_GET_FW_VERSION: | ||
27 | return "WMI_GET_FW_VERSION"; | ||
26 | case WMI_DISABLE_INTR_CMDID: | 28 | case WMI_DISABLE_INTR_CMDID: |
27 | return "WMI_DISABLE_INTR_CMDID"; | 29 | return "WMI_DISABLE_INTR_CMDID"; |
28 | case WMI_ENABLE_INTR_CMDID: | 30 | case WMI_ENABLE_INTR_CMDID: |
29 | return "WMI_ENABLE_INTR_CMDID"; | 31 | return "WMI_ENABLE_INTR_CMDID"; |
30 | case WMI_RX_LINK_CMDID: | ||
31 | return "WMI_RX_LINK_CMDID"; | ||
32 | case WMI_ATH_INIT_CMDID: | 32 | case WMI_ATH_INIT_CMDID: |
33 | return "WMI_ATH_INIT_CMDID"; | 33 | return "WMI_ATH_INIT_CMDID"; |
34 | case WMI_ABORT_TXQ_CMDID: | 34 | case WMI_ABORT_TXQ_CMDID: |
35 | return "WMI_ABORT_TXQ_CMDID"; | 35 | return "WMI_ABORT_TXQ_CMDID"; |
36 | case WMI_STOP_TX_DMA_CMDID: | 36 | case WMI_STOP_TX_DMA_CMDID: |
37 | return "WMI_STOP_TX_DMA_CMDID"; | 37 | return "WMI_STOP_TX_DMA_CMDID"; |
38 | case WMI_STOP_DMA_RECV_CMDID: | ||
39 | return "WMI_STOP_DMA_RECV_CMDID"; | ||
40 | case WMI_ABORT_TX_DMA_CMDID: | 38 | case WMI_ABORT_TX_DMA_CMDID: |
41 | return "WMI_ABORT_TX_DMA_CMDID"; | 39 | return "WMI_ABORT_TX_DMA_CMDID"; |
42 | case WMI_DRAIN_TXQ_CMDID: | 40 | case WMI_DRAIN_TXQ_CMDID: |
@@ -51,8 +49,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
51 | return "WMI_FLUSH_RECV_CMDID"; | 49 | return "WMI_FLUSH_RECV_CMDID"; |
52 | case WMI_SET_MODE_CMDID: | 50 | case WMI_SET_MODE_CMDID: |
53 | return "WMI_SET_MODE_CMDID"; | 51 | return "WMI_SET_MODE_CMDID"; |
54 | case WMI_RESET_CMDID: | ||
55 | return "WMI_RESET_CMDID"; | ||
56 | case WMI_NODE_CREATE_CMDID: | 52 | case WMI_NODE_CREATE_CMDID: |
57 | return "WMI_NODE_CREATE_CMDID"; | 53 | return "WMI_NODE_CREATE_CMDID"; |
58 | case WMI_NODE_REMOVE_CMDID: | 54 | case WMI_NODE_REMOVE_CMDID: |
@@ -61,8 +57,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
61 | return "WMI_VAP_REMOVE_CMDID"; | 57 | return "WMI_VAP_REMOVE_CMDID"; |
62 | case WMI_VAP_CREATE_CMDID: | 58 | case WMI_VAP_CREATE_CMDID: |
63 | return "WMI_VAP_CREATE_CMDID"; | 59 | return "WMI_VAP_CREATE_CMDID"; |
64 | case WMI_BEACON_UPDATE_CMDID: | ||
65 | return "WMI_BEACON_UPDATE_CMDID"; | ||
66 | case WMI_REG_READ_CMDID: | 60 | case WMI_REG_READ_CMDID: |
67 | return "WMI_REG_READ_CMDID"; | 61 | return "WMI_REG_READ_CMDID"; |
68 | case WMI_REG_WRITE_CMDID: | 62 | case WMI_REG_WRITE_CMDID: |
@@ -71,20 +65,20 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
71 | return "WMI_RC_STATE_CHANGE_CMDID"; | 65 | return "WMI_RC_STATE_CHANGE_CMDID"; |
72 | case WMI_RC_RATE_UPDATE_CMDID: | 66 | case WMI_RC_RATE_UPDATE_CMDID: |
73 | return "WMI_RC_RATE_UPDATE_CMDID"; | 67 | return "WMI_RC_RATE_UPDATE_CMDID"; |
74 | case WMI_DEBUG_INFO_CMDID: | ||
75 | return "WMI_DEBUG_INFO_CMDID"; | ||
76 | case WMI_HOST_ATTACH: | ||
77 | return "WMI_HOST_ATTACH"; | ||
78 | case WMI_TARGET_IC_UPDATE_CMDID: | 68 | case WMI_TARGET_IC_UPDATE_CMDID: |
79 | return "WMI_TARGET_IC_UPDATE_CMDID"; | 69 | return "WMI_TARGET_IC_UPDATE_CMDID"; |
80 | case WMI_TGT_STATS_CMDID: | ||
81 | return "WMI_TGT_STATS_CMDID"; | ||
82 | case WMI_TX_AGGR_ENABLE_CMDID: | 70 | case WMI_TX_AGGR_ENABLE_CMDID: |
83 | return "WMI_TX_AGGR_ENABLE_CMDID"; | 71 | return "WMI_TX_AGGR_ENABLE_CMDID"; |
84 | case WMI_TGT_DETACH_CMDID: | 72 | case WMI_TGT_DETACH_CMDID: |
85 | return "WMI_TGT_DETACH_CMDID"; | 73 | return "WMI_TGT_DETACH_CMDID"; |
86 | case WMI_TGT_TXQ_ENABLE_CMDID: | 74 | case WMI_NODE_UPDATE_CMDID: |
87 | return "WMI_TGT_TXQ_ENABLE_CMDID"; | 75 | return "WMI_NODE_UPDATE_CMDID"; |
76 | case WMI_INT_STATS_CMDID: | ||
77 | return "WMI_INT_STATS_CMDID"; | ||
78 | case WMI_TX_STATS_CMDID: | ||
79 | return "WMI_TX_STATS_CMDID"; | ||
80 | case WMI_RX_STATS_CMDID: | ||
81 | return "WMI_RX_STATS_CMDID"; | ||
88 | case WMI_AGGR_LIMIT_CMD: | 82 | case WMI_AGGR_LIMIT_CMD: |
89 | return "WMI_AGGR_LIMIT_CMD"; | 83 | return "WMI_AGGR_LIMIT_CMD"; |
90 | } | 84 | } |
@@ -102,9 +96,15 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) | |||
102 | 96 | ||
103 | wmi->drv_priv = priv; | 97 | wmi->drv_priv = priv; |
104 | wmi->stopped = false; | 98 | wmi->stopped = false; |
99 | skb_queue_head_init(&wmi->wmi_event_queue); | ||
100 | spin_lock_init(&wmi->wmi_lock); | ||
101 | spin_lock_init(&wmi->event_lock); | ||
105 | mutex_init(&wmi->op_mutex); | 102 | mutex_init(&wmi->op_mutex); |
106 | mutex_init(&wmi->multi_write_mutex); | 103 | mutex_init(&wmi->multi_write_mutex); |
107 | init_completion(&wmi->cmd_wait); | 104 | init_completion(&wmi->cmd_wait); |
105 | INIT_LIST_HEAD(&wmi->pending_tx_events); | ||
106 | tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet, | ||
107 | (unsigned long)wmi); | ||
108 | 108 | ||
109 | return wmi; | 109 | return wmi; |
110 | } | 110 | } |
@@ -120,11 +120,65 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) | |||
120 | kfree(priv->wmi); | 120 | kfree(priv->wmi); |
121 | } | 121 | } |
122 | 122 | ||
123 | void ath9k_swba_tasklet(unsigned long data) | 123 | void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv) |
124 | { | 124 | { |
125 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | 125 | unsigned long flags; |
126 | 126 | ||
127 | ath9k_htc_swba(priv, priv->wmi->beacon_pending); | 127 | tasklet_kill(&priv->wmi->wmi_event_tasklet); |
128 | spin_lock_irqsave(&priv->wmi->wmi_lock, flags); | ||
129 | __skb_queue_purge(&priv->wmi->wmi_event_queue); | ||
130 | spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); | ||
131 | } | ||
132 | |||
133 | void ath9k_wmi_event_tasklet(unsigned long data) | ||
134 | { | ||
135 | struct wmi *wmi = (struct wmi *)data; | ||
136 | struct ath9k_htc_priv *priv = wmi->drv_priv; | ||
137 | struct wmi_cmd_hdr *hdr; | ||
138 | void *wmi_event; | ||
139 | struct wmi_event_swba *swba; | ||
140 | struct sk_buff *skb = NULL; | ||
141 | unsigned long flags; | ||
142 | u16 cmd_id; | ||
143 | |||
144 | do { | ||
145 | spin_lock_irqsave(&wmi->wmi_lock, flags); | ||
146 | skb = __skb_dequeue(&wmi->wmi_event_queue); | ||
147 | if (!skb) { | ||
148 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
149 | return; | ||
150 | } | ||
151 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
152 | |||
153 | hdr = (struct wmi_cmd_hdr *) skb->data; | ||
154 | cmd_id = be16_to_cpu(hdr->command_id); | ||
155 | wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); | ||
156 | |||
157 | switch (cmd_id) { | ||
158 | case WMI_SWBA_EVENTID: | ||
159 | swba = (struct wmi_event_swba *) wmi_event; | ||
160 | ath9k_htc_swba(priv, swba); | ||
161 | break; | ||
162 | case WMI_FATAL_EVENTID: | ||
163 | ieee80211_queue_work(wmi->drv_priv->hw, | ||
164 | &wmi->drv_priv->fatal_work); | ||
165 | break; | ||
166 | case WMI_TXSTATUS_EVENTID: | ||
167 | spin_lock_bh(&priv->tx.tx_lock); | ||
168 | if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { | ||
169 | spin_unlock_bh(&priv->tx.tx_lock); | ||
170 | break; | ||
171 | } | ||
172 | spin_unlock_bh(&priv->tx.tx_lock); | ||
173 | |||
174 | ath9k_htc_txstatus(priv, wmi_event); | ||
175 | break; | ||
176 | default: | ||
177 | break; | ||
178 | } | ||
179 | |||
180 | kfree_skb(skb); | ||
181 | } while (1); | ||
128 | } | 182 | } |
129 | 183 | ||
130 | void ath9k_fatal_work(struct work_struct *work) | 184 | void ath9k_fatal_work(struct work_struct *work) |
@@ -153,10 +207,6 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, | |||
153 | struct wmi *wmi = (struct wmi *) priv; | 207 | struct wmi *wmi = (struct wmi *) priv; |
154 | struct wmi_cmd_hdr *hdr; | 208 | struct wmi_cmd_hdr *hdr; |
155 | u16 cmd_id; | 209 | u16 cmd_id; |
156 | void *wmi_event; | ||
157 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
158 | __be32 txrate; | ||
159 | #endif | ||
160 | 210 | ||
161 | if (unlikely(wmi->stopped)) | 211 | if (unlikely(wmi->stopped)) |
162 | goto free_skb; | 212 | goto free_skb; |
@@ -165,26 +215,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, | |||
165 | cmd_id = be16_to_cpu(hdr->command_id); | 215 | cmd_id = be16_to_cpu(hdr->command_id); |
166 | 216 | ||
167 | if (cmd_id & 0x1000) { | 217 | if (cmd_id & 0x1000) { |
168 | wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); | 218 | spin_lock(&wmi->wmi_lock); |
169 | switch (cmd_id) { | 219 | __skb_queue_tail(&wmi->wmi_event_queue, skb); |
170 | case WMI_SWBA_EVENTID: | 220 | spin_unlock(&wmi->wmi_lock); |
171 | wmi->beacon_pending = *(u8 *)wmi_event; | 221 | tasklet_schedule(&wmi->wmi_event_tasklet); |
172 | tasklet_schedule(&wmi->drv_priv->swba_tasklet); | ||
173 | break; | ||
174 | case WMI_FATAL_EVENTID: | ||
175 | ieee80211_queue_work(wmi->drv_priv->hw, | ||
176 | &wmi->drv_priv->fatal_work); | ||
177 | break; | ||
178 | case WMI_TXRATE_EVENTID: | ||
179 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
180 | txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; | ||
181 | wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); | ||
182 | #endif | ||
183 | break; | ||
184 | default: | ||
185 | break; | ||
186 | } | ||
187 | kfree_skb(skb); | ||
188 | return; | 222 | return; |
189 | } | 223 | } |
190 | 224 | ||
@@ -243,7 +277,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, | |||
243 | hdr->command_id = cpu_to_be16(cmd); | 277 | hdr->command_id = cpu_to_be16(cmd); |
244 | hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); | 278 | hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); |
245 | 279 | ||
246 | return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL); | 280 | return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid); |
247 | } | 281 | } |
248 | 282 | ||
249 | int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | 283 | int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 42084277522d..02ecb9f06db0 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h | |||
@@ -17,7 +17,6 @@ | |||
17 | #ifndef WMI_H | 17 | #ifndef WMI_H |
18 | #define WMI_H | 18 | #define WMI_H |
19 | 19 | ||
20 | |||
21 | struct wmi_event_txrate { | 20 | struct wmi_event_txrate { |
22 | __be32 txrate; | 21 | __be32 txrate; |
23 | struct { | 22 | struct { |
@@ -31,18 +30,65 @@ struct wmi_cmd_hdr { | |||
31 | __be16 seq_no; | 30 | __be16 seq_no; |
32 | } __packed; | 31 | } __packed; |
33 | 32 | ||
33 | struct wmi_fw_version { | ||
34 | __be16 major; | ||
35 | __be16 minor; | ||
36 | |||
37 | } __packed; | ||
38 | |||
39 | struct wmi_event_swba { | ||
40 | __be64 tsf; | ||
41 | u8 beacon_pending; | ||
42 | }; | ||
43 | |||
44 | /* | ||
45 | * 64 - HTC header - WMI header - 1 / txstatus | ||
46 | * And some other hdr. space is also accounted for. | ||
47 | * 12 seems to be the magic number. | ||
48 | */ | ||
49 | #define HTC_MAX_TX_STATUS 12 | ||
50 | |||
51 | #define ATH9K_HTC_TXSTAT_ACK BIT(0) | ||
52 | #define ATH9K_HTC_TXSTAT_FILT BIT(1) | ||
53 | #define ATH9K_HTC_TXSTAT_RTC_CTS BIT(2) | ||
54 | #define ATH9K_HTC_TXSTAT_MCS BIT(3) | ||
55 | #define ATH9K_HTC_TXSTAT_CW40 BIT(4) | ||
56 | #define ATH9K_HTC_TXSTAT_SGI BIT(5) | ||
57 | |||
58 | /* | ||
59 | * Legacy rates are indicated as indices. | ||
60 | * HT rates are indicated as dot11 numbers. | ||
61 | * This allows us to resrict the rate field | ||
62 | * to 4 bits. | ||
63 | */ | ||
64 | #define ATH9K_HTC_TXSTAT_RATE 0x0f | ||
65 | #define ATH9K_HTC_TXSTAT_RATE_S 0 | ||
66 | |||
67 | #define ATH9K_HTC_TXSTAT_EPID 0xf0 | ||
68 | #define ATH9K_HTC_TXSTAT_EPID_S 4 | ||
69 | |||
70 | struct __wmi_event_txstatus { | ||
71 | u8 cookie; | ||
72 | u8 ts_rate; /* Also holds EP ID */ | ||
73 | u8 ts_flags; | ||
74 | }; | ||
75 | |||
76 | struct wmi_event_txstatus { | ||
77 | u8 cnt; | ||
78 | struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS]; | ||
79 | } __packed; | ||
80 | |||
34 | enum wmi_cmd_id { | 81 | enum wmi_cmd_id { |
35 | WMI_ECHO_CMDID = 0x0001, | 82 | WMI_ECHO_CMDID = 0x0001, |
36 | WMI_ACCESS_MEMORY_CMDID, | 83 | WMI_ACCESS_MEMORY_CMDID, |
37 | 84 | ||
38 | /* Commands to Target */ | 85 | /* Commands to Target */ |
86 | WMI_GET_FW_VERSION, | ||
39 | WMI_DISABLE_INTR_CMDID, | 87 | WMI_DISABLE_INTR_CMDID, |
40 | WMI_ENABLE_INTR_CMDID, | 88 | WMI_ENABLE_INTR_CMDID, |
41 | WMI_RX_LINK_CMDID, | ||
42 | WMI_ATH_INIT_CMDID, | 89 | WMI_ATH_INIT_CMDID, |
43 | WMI_ABORT_TXQ_CMDID, | 90 | WMI_ABORT_TXQ_CMDID, |
44 | WMI_STOP_TX_DMA_CMDID, | 91 | WMI_STOP_TX_DMA_CMDID, |
45 | WMI_STOP_DMA_RECV_CMDID, | ||
46 | WMI_ABORT_TX_DMA_CMDID, | 92 | WMI_ABORT_TX_DMA_CMDID, |
47 | WMI_DRAIN_TXQ_CMDID, | 93 | WMI_DRAIN_TXQ_CMDID, |
48 | WMI_DRAIN_TXQ_ALL_CMDID, | 94 | WMI_DRAIN_TXQ_ALL_CMDID, |
@@ -50,23 +96,21 @@ enum wmi_cmd_id { | |||
50 | WMI_STOP_RECV_CMDID, | 96 | WMI_STOP_RECV_CMDID, |
51 | WMI_FLUSH_RECV_CMDID, | 97 | WMI_FLUSH_RECV_CMDID, |
52 | WMI_SET_MODE_CMDID, | 98 | WMI_SET_MODE_CMDID, |
53 | WMI_RESET_CMDID, | ||
54 | WMI_NODE_CREATE_CMDID, | 99 | WMI_NODE_CREATE_CMDID, |
55 | WMI_NODE_REMOVE_CMDID, | 100 | WMI_NODE_REMOVE_CMDID, |
56 | WMI_VAP_REMOVE_CMDID, | 101 | WMI_VAP_REMOVE_CMDID, |
57 | WMI_VAP_CREATE_CMDID, | 102 | WMI_VAP_CREATE_CMDID, |
58 | WMI_BEACON_UPDATE_CMDID, | ||
59 | WMI_REG_READ_CMDID, | 103 | WMI_REG_READ_CMDID, |
60 | WMI_REG_WRITE_CMDID, | 104 | WMI_REG_WRITE_CMDID, |
61 | WMI_RC_STATE_CHANGE_CMDID, | 105 | WMI_RC_STATE_CHANGE_CMDID, |
62 | WMI_RC_RATE_UPDATE_CMDID, | 106 | WMI_RC_RATE_UPDATE_CMDID, |
63 | WMI_DEBUG_INFO_CMDID, | ||
64 | WMI_HOST_ATTACH, | ||
65 | WMI_TARGET_IC_UPDATE_CMDID, | 107 | WMI_TARGET_IC_UPDATE_CMDID, |
66 | WMI_TGT_STATS_CMDID, | ||
67 | WMI_TX_AGGR_ENABLE_CMDID, | 108 | WMI_TX_AGGR_ENABLE_CMDID, |
68 | WMI_TGT_DETACH_CMDID, | 109 | WMI_TGT_DETACH_CMDID, |
69 | WMI_TGT_TXQ_ENABLE_CMDID, | 110 | WMI_NODE_UPDATE_CMDID, |
111 | WMI_INT_STATS_CMDID, | ||
112 | WMI_TX_STATS_CMDID, | ||
113 | WMI_RX_STATS_CMDID, | ||
70 | WMI_AGGR_LIMIT_CMD = 0x0026, | 114 | WMI_AGGR_LIMIT_CMD = 0x0026, |
71 | }; | 115 | }; |
72 | 116 | ||
@@ -76,9 +120,8 @@ enum wmi_event_id { | |||
76 | WMI_FATAL_EVENTID, | 120 | WMI_FATAL_EVENTID, |
77 | WMI_TXTO_EVENTID, | 121 | WMI_TXTO_EVENTID, |
78 | WMI_BMISS_EVENTID, | 122 | WMI_BMISS_EVENTID, |
79 | WMI_WLAN_TXCOMP_EVENTID, | ||
80 | WMI_DELBA_EVENTID, | 123 | WMI_DELBA_EVENTID, |
81 | WMI_TXRATE_EVENTID, | 124 | WMI_TXSTATUS_EVENTID, |
82 | }; | 125 | }; |
83 | 126 | ||
84 | #define MAX_CMD_NUMBER 62 | 127 | #define MAX_CMD_NUMBER 62 |
@@ -88,6 +131,12 @@ struct register_write { | |||
88 | __be32 val; | 131 | __be32 val; |
89 | }; | 132 | }; |
90 | 133 | ||
134 | struct ath9k_htc_tx_event { | ||
135 | int count; | ||
136 | struct __wmi_event_txstatus txs; | ||
137 | struct list_head list; | ||
138 | }; | ||
139 | |||
91 | struct wmi { | 140 | struct wmi { |
92 | struct ath9k_htc_priv *drv_priv; | 141 | struct ath9k_htc_priv *drv_priv; |
93 | struct htc_target *htc; | 142 | struct htc_target *htc; |
@@ -95,12 +144,16 @@ struct wmi { | |||
95 | struct mutex op_mutex; | 144 | struct mutex op_mutex; |
96 | struct completion cmd_wait; | 145 | struct completion cmd_wait; |
97 | enum wmi_cmd_id last_cmd_id; | 146 | enum wmi_cmd_id last_cmd_id; |
147 | struct sk_buff_head wmi_event_queue; | ||
148 | struct tasklet_struct wmi_event_tasklet; | ||
98 | u16 tx_seq_id; | 149 | u16 tx_seq_id; |
99 | u8 *cmd_rsp_buf; | 150 | u8 *cmd_rsp_buf; |
100 | u32 cmd_rsp_len; | 151 | u32 cmd_rsp_len; |
101 | bool stopped; | 152 | bool stopped; |
102 | 153 | ||
103 | u8 beacon_pending; | 154 | struct list_head pending_tx_events; |
155 | spinlock_t event_lock; | ||
156 | |||
104 | spinlock_t wmi_lock; | 157 | spinlock_t wmi_lock; |
105 | 158 | ||
106 | atomic_t mwrite_cnt; | 159 | atomic_t mwrite_cnt; |
@@ -117,8 +170,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
117 | u8 *cmd_buf, u32 cmd_len, | 170 | u8 *cmd_buf, u32 cmd_len, |
118 | u8 *rsp_buf, u32 rsp_len, | 171 | u8 *rsp_buf, u32 rsp_len, |
119 | u32 timeout); | 172 | u32 timeout); |
120 | void ath9k_swba_tasklet(unsigned long data); | 173 | void ath9k_wmi_event_tasklet(unsigned long data); |
121 | void ath9k_fatal_work(struct work_struct *work); | 174 | void ath9k_fatal_work(struct work_struct *work); |
175 | void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); | ||
122 | 176 | ||
123 | #define WMI_CMD(_wmi_cmd) \ | 177 | #define WMI_CMD(_wmi_cmd) \ |
124 | do { \ | 178 | do { \ |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index f828f294ba89..7e3b29015dda 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -97,8 +97,8 @@ static const struct ieee80211_regdomain ath_world_regdom_66_69 = { | |||
97 | } | 97 | } |
98 | }; | 98 | }; |
99 | 99 | ||
100 | /* Can be used by 0x67, 0x6A and 0x68 */ | 100 | /* Can be used by 0x67, 0x68, 0x6A and 0x6C */ |
101 | static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = { | 101 | static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { |
102 | .n_reg_rules = 4, | 102 | .n_reg_rules = 4, |
103 | .alpha2 = "99", | 103 | .alpha2 = "99", |
104 | .reg_rules = { | 104 | .reg_rules = { |
@@ -151,7 +151,8 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) | |||
151 | case 0x67: | 151 | case 0x67: |
152 | case 0x68: | 152 | case 0x68: |
153 | case 0x6A: | 153 | case 0x6A: |
154 | return &ath_world_regdom_67_68_6A; | 154 | case 0x6C: |
155 | return &ath_world_regdom_67_68_6A_6C; | ||
155 | default: | 156 | default: |
156 | WARN_ON(1); | 157 | WARN_ON(1); |
157 | return ath_default_world_regdomain(); | 158 | return ath_default_world_regdomain(); |
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h index 5c2cfe694152..24b53839fc3a 100644 --- a/drivers/net/wireless/ath/regd_common.h +++ b/drivers/net/wireless/ath/regd_common.h | |||
@@ -86,6 +86,7 @@ enum EnumRd { | |||
86 | WOR9_WORLD = 0x69, | 86 | WOR9_WORLD = 0x69, |
87 | WORA_WORLD = 0x6A, | 87 | WORA_WORLD = 0x6A, |
88 | WORB_WORLD = 0x6B, | 88 | WORB_WORLD = 0x6B, |
89 | WORC_WORLD = 0x6C, | ||
89 | 90 | ||
90 | MKK3_MKKB = 0x80, | 91 | MKK3_MKKB = 0x80, |
91 | MKK3_MKKA2 = 0x81, | 92 | MKK3_MKKA2 = 0x81, |
@@ -282,6 +283,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = { | |||
282 | {WOR9_WORLD, NO_CTL, NO_CTL}, | 283 | {WOR9_WORLD, NO_CTL, NO_CTL}, |
283 | {WORA_WORLD, NO_CTL, NO_CTL}, | 284 | {WORA_WORLD, NO_CTL, NO_CTL}, |
284 | {WORB_WORLD, NO_CTL, NO_CTL}, | 285 | {WORB_WORLD, NO_CTL, NO_CTL}, |
286 | {WORC_WORLD, NO_CTL, NO_CTL}, | ||
285 | }; | 287 | }; |
286 | 288 | ||
287 | static struct country_code_to_enum_rd allCountries[] = { | 289 | static struct country_code_to_enum_rd allCountries[] = { |
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c index 31ac672b64e1..89509392ef5d 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c | |||
@@ -2860,7 +2860,6 @@ static struct rate_control_ops rs_4965_ops = { | |||
2860 | 2860 | ||
2861 | int iwl4965_rate_control_register(void) | 2861 | int iwl4965_rate_control_register(void) |
2862 | { | 2862 | { |
2863 | pr_err("Registering 4965 rate control operations\n"); | ||
2864 | return ieee80211_rate_control_register(&rs_4965_ops); | 2863 | return ieee80211_rate_control_register(&rs_4965_ops); |
2865 | } | 2864 | } |
2866 | 2865 | ||
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 73a6e62f5680..d64065ff235c 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c | |||
@@ -242,9 +242,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, | |||
242 | * | 242 | * |
243 | * Handling includes changing the header fields into CPU format. | 243 | * Handling includes changing the header fields into CPU format. |
244 | */ | 244 | */ |
245 | int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, | 245 | int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) |
246 | struct host_cmd_ds_command *resp, | ||
247 | void *data_buf) | ||
248 | { | 246 | { |
249 | struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL; | 247 | struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL; |
250 | struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; | 248 | struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; |
@@ -298,8 +296,7 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, | |||
298 | * - Setting AMSDU control parameters (for SET only) | 296 | * - Setting AMSDU control parameters (for SET only) |
299 | * - Ensuring correct endian-ness | 297 | * - Ensuring correct endian-ness |
300 | */ | 298 | */ |
301 | int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, | 299 | int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, |
302 | struct host_cmd_ds_command *cmd, | ||
303 | int cmd_action, void *data_buf) | 300 | int cmd_action, void *data_buf) |
304 | { | 301 | { |
305 | struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = | 302 | struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = |
@@ -331,8 +328,7 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, | |||
331 | * | 328 | * |
332 | * Handling includes changing the header fields into CPU format. | 329 | * Handling includes changing the header fields into CPU format. |
333 | */ | 330 | */ |
334 | int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, | 331 | int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, |
335 | struct host_cmd_ds_command *resp, | ||
336 | void *data_buf) | 332 | void *data_buf) |
337 | { | 333 | { |
338 | struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL; | 334 | struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL; |
@@ -357,8 +353,7 @@ int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, | |||
357 | * - Setting HT Tx capability and HT Tx information fields | 353 | * - Setting HT Tx capability and HT Tx information fields |
358 | * - Ensuring correct endian-ness | 354 | * - Ensuring correct endian-ness |
359 | */ | 355 | */ |
360 | int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, | 356 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, |
361 | struct host_cmd_ds_command *cmd, | ||
362 | u16 cmd_action, void *data_buf) | 357 | u16 cmd_action, void *data_buf) |
363 | { | 358 | { |
364 | struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; | 359 | struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; |
@@ -541,11 +536,8 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, | |||
541 | else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K) | 536 | else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K) |
542 | curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K; | 537 | curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K; |
543 | if (curr_tx_buf_size != tx_buf) | 538 | if (curr_tx_buf_size != tx_buf) |
544 | mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, | 539 | mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, |
545 | HostCmd_ACT_GEN_SET, 0, | 540 | HostCmd_ACT_GEN_SET, 0, &tx_buf); |
546 | NULL, &tx_buf); | ||
547 | |||
548 | return; | ||
549 | } | 541 | } |
550 | 542 | ||
551 | /* | 543 | /* |
@@ -583,8 +575,6 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, | |||
583 | list_del(&tx_ba_tsr_tbl->list); | 575 | list_del(&tx_ba_tsr_tbl->list); |
584 | 576 | ||
585 | kfree(tx_ba_tsr_tbl); | 577 | kfree(tx_ba_tsr_tbl); |
586 | |||
587 | return; | ||
588 | } | 578 | } |
589 | 579 | ||
590 | /* | 580 | /* |
@@ -663,8 +653,6 @@ void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, | |||
663 | list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr); | 653 | list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr); |
664 | spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); | 654 | spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); |
665 | } | 655 | } |
666 | |||
667 | return; | ||
668 | } | 656 | } |
669 | 657 | ||
670 | /* | 658 | /* |
@@ -694,8 +682,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac) | |||
694 | memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); | 682 | memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); |
695 | 683 | ||
696 | /* We don't wait for the response of this command */ | 684 | /* We don't wait for the response of this command */ |
697 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ, | 685 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ, |
698 | 0, 0, NULL, &add_ba_req); | 686 | 0, 0, &add_ba_req); |
699 | 687 | ||
700 | return ret; | 688 | return ret; |
701 | } | 689 | } |
@@ -722,8 +710,8 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, | |||
722 | memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); | 710 | memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); |
723 | 711 | ||
724 | /* We don't wait for the response of this command */ | 712 | /* We don't wait for the response of this command */ |
725 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, | 713 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, |
726 | HostCmd_ACT_GEN_SET, 0, NULL, &delba); | 714 | HostCmd_ACT_GEN_SET, 0, &delba); |
727 | 715 | ||
728 | return ret; | 716 | return ret; |
729 | } | 717 | } |
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 71a853e61b61..02602ff30cbf 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h | |||
@@ -28,15 +28,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, | |||
28 | struct host_cmd_ds_command *resp); | 28 | struct host_cmd_ds_command *resp); |
29 | int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, | 29 | int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, |
30 | struct host_cmd_ds_command *resp); | 30 | struct host_cmd_ds_command *resp); |
31 | int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, | 31 | int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, |
32 | struct host_cmd_ds_command *resp, | ||
33 | void *data_buf); | 32 | void *data_buf); |
34 | int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, | 33 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, |
35 | struct host_cmd_ds_command *cmd, | ||
36 | u16 cmd_action, void *data_buf); | ||
37 | |||
38 | int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, | ||
39 | struct host_cmd_ds_command *cmd, | ||
40 | u16 cmd_action, void *data_buf); | 34 | u16 cmd_action, void *data_buf); |
41 | 35 | ||
42 | int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | 36 | int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, |
@@ -67,24 +61,19 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, | |||
67 | struct mwifiex_ds_rx_reorder_tbl *buf); | 61 | struct mwifiex_ds_rx_reorder_tbl *buf); |
68 | int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, | 62 | int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, |
69 | struct mwifiex_ds_tx_ba_stream_tbl *buf); | 63 | struct mwifiex_ds_tx_ba_stream_tbl *buf); |
70 | int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, | 64 | int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, |
71 | struct host_cmd_ds_command | ||
72 | *resp, | ||
73 | void *data_buf); | 65 | void *data_buf); |
74 | int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, | 66 | int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, |
75 | struct host_cmd_ds_command *cmd, | 67 | struct host_cmd_ds_command *cmd, |
76 | int cmd_action, void *data_buf); | 68 | int cmd_action, void *data_buf); |
77 | int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, | 69 | int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, |
78 | struct host_cmd_ds_command *cmd, | 70 | int cmd_action, void *data_buf); |
79 | int cmd_action, | ||
80 | void *data_buf); | ||
81 | 71 | ||
82 | /* | 72 | /* |
83 | * This function checks whether AMPDU is allowed or not for a particular TID. | 73 | * This function checks whether AMPDU is allowed or not for a particular TID. |
84 | */ | 74 | */ |
85 | static inline u8 | 75 | static inline u8 |
86 | mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, | 76 | mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid) |
87 | struct mwifiex_ra_list_tbl *ptr, int tid) | ||
88 | { | 77 | { |
89 | return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) | 78 | return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) |
90 | ? true : false); | 79 | ? true : false); |
@@ -94,8 +83,7 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, | |||
94 | * This function checks whether AMSDU is allowed or not for a particular TID. | 83 | * This function checks whether AMSDU is allowed or not for a particular TID. |
95 | */ | 84 | */ |
96 | static inline u8 | 85 | static inline u8 |
97 | mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, | 86 | mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) |
98 | struct mwifiex_ra_list_tbl *ptr, int tid) | ||
99 | { | 87 | { |
100 | return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) | 88 | return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) |
101 | && ((priv->is_data_rate_auto) | 89 | && ((priv->is_data_rate_auto) |
@@ -104,23 +92,21 @@ mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, | |||
104 | } | 92 | } |
105 | 93 | ||
106 | /* | 94 | /* |
107 | * This function checks whether a BA stream is available or not. | 95 | * This function checks whether a space is available for new BA stream or not. |
108 | */ | 96 | */ |
109 | static inline u8 | 97 | static inline u8 mwifiex_space_avail_for_new_ba_stream( |
110 | mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) | 98 | struct mwifiex_adapter *adapter) |
111 | { | 99 | { |
112 | struct mwifiex_private *pmpriv = NULL; | 100 | struct mwifiex_private *priv; |
113 | u8 i = 0; | 101 | u8 i; |
114 | u32 ba_stream_num = 0; | 102 | u32 ba_stream_num = 0; |
115 | 103 | ||
116 | for (i = 0; i < priv->adapter->priv_num; i++) { | 104 | for (i = 0; i < adapter->priv_num; i++) { |
117 | pmpriv = priv->adapter->priv[i]; | 105 | priv = adapter->priv[i]; |
118 | if (pmpriv) | 106 | if (priv) |
119 | ba_stream_num += | 107 | ba_stream_num += mwifiex_wmm_list_len( |
120 | mwifiex_wmm_list_len(priv->adapter, | 108 | (struct list_head *) |
121 | (struct list_head | 109 | &priv->tx_ba_stream_tbl_ptr); |
122 | *) &pmpriv-> | ||
123 | tx_ba_stream_tbl_ptr); | ||
124 | } | 110 | } |
125 | 111 | ||
126 | return ((ba_stream_num < | 112 | return ((ba_stream_num < |
@@ -133,8 +119,7 @@ mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) | |||
133 | * Upon successfully locating, both the TID and the RA are returned. | 119 | * Upon successfully locating, both the TID and the RA are returned. |
134 | */ | 120 | */ |
135 | static inline u8 | 121 | static inline u8 |
136 | mwifiex_find_stream_to_delete(struct mwifiex_private *priv, | 122 | mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid, |
137 | struct mwifiex_ra_list_tbl *ptr, int ptr_tid, | ||
138 | int *ptid, u8 *ra) | 123 | int *ptid, u8 *ra) |
139 | { | 124 | { |
140 | int tid; | 125 | int tid; |
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index c2abced66957..c9fb0627de43 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c | |||
@@ -44,8 +44,7 @@ | |||
44 | * MSDU => |DA|SA|Length|SNAP|...... ..| | 44 | * MSDU => |DA|SA|Length|SNAP|...... ..| |
45 | */ | 45 | */ |
46 | static int | 46 | static int |
47 | mwifiex_11n_form_amsdu_pkt(struct mwifiex_adapter *adapter, | 47 | mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr, |
48 | struct sk_buff *skb_aggr, | ||
49 | struct sk_buff *skb_src, int *pad) | 48 | struct sk_buff *skb_src, int *pad) |
50 | 49 | ||
51 | { | 50 | { |
@@ -324,7 +323,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
324 | 323 | ||
325 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 324 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
326 | ra_list_flags); | 325 | ra_list_flags); |
327 | mwifiex_11n_form_amsdu_pkt(adapter, skb_aggr, skb_src, &pad); | 326 | mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); |
328 | 327 | ||
329 | mwifiex_write_data_complete(adapter, skb_src, 0); | 328 | mwifiex_write_data_complete(adapter, skb_src, 0); |
330 | 329 | ||
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 8e94e620e6f4..755e5d533c03 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -309,8 +309,6 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, | |||
309 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); | 309 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
310 | list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr); | 310 | list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr); |
311 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); | 311 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
312 | |||
313 | return; | ||
314 | } | 312 | } |
315 | 313 | ||
316 | /* | 314 | /* |
@@ -321,8 +319,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, | |||
321 | * - Setting add BA request buffer | 319 | * - Setting add BA request buffer |
322 | * - Ensuring correct endian-ness | 320 | * - Ensuring correct endian-ness |
323 | */ | 321 | */ |
324 | int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, | 322 | int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) |
325 | struct host_cmd_ds_command *cmd, void *data_buf) | ||
326 | { | 323 | { |
327 | struct host_cmd_ds_11n_addba_req *add_ba_req = | 324 | struct host_cmd_ds_11n_addba_req *add_ba_req = |
328 | (struct host_cmd_ds_11n_addba_req *) | 325 | (struct host_cmd_ds_11n_addba_req *) |
@@ -393,8 +390,7 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, | |||
393 | * - Setting del BA request buffer | 390 | * - Setting del BA request buffer |
394 | * - Ensuring correct endian-ness | 391 | * - Ensuring correct endian-ness |
395 | */ | 392 | */ |
396 | int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, | 393 | int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf) |
397 | struct host_cmd_ds_command *cmd, void *data_buf) | ||
398 | { | 394 | { |
399 | struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) | 395 | struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) |
400 | &cmd->params.del_ba; | 396 | &cmd->params.del_ba; |
@@ -609,9 +605,7 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, | |||
609 | delba.del_ba_param_set |= cpu_to_le16( | 605 | delba.del_ba_param_set |= cpu_to_le16( |
610 | (u16) event->origninator << DELBA_INITIATOR_POS); | 606 | (u16) event->origninator << DELBA_INITIATOR_POS); |
611 | delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); | 607 | delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); |
612 | mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, NULL, &delba); | 608 | mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba); |
613 | |||
614 | return; | ||
615 | } | 609 | } |
616 | 610 | ||
617 | /* | 611 | /* |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 42f569035745..f3ca8c8c18f9 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h | |||
@@ -49,14 +49,12 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, | |||
49 | int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, | 49 | int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, |
50 | struct host_cmd_ds_command | 50 | struct host_cmd_ds_command |
51 | *resp); | 51 | *resp); |
52 | int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, | 52 | int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, |
53 | struct host_cmd_ds_command *cmd, | ||
54 | void *data_buf); | 53 | void *data_buf); |
55 | int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, | 54 | int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, |
56 | struct host_cmd_ds_command | 55 | struct host_cmd_ds_command |
57 | *cmd, void *data_buf); | 56 | *cmd, void *data_buf); |
58 | int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, | 57 | int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, |
59 | struct host_cmd_ds_command *cmd, | ||
60 | void *data_buf); | 58 | void *data_buf); |
61 | void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); | 59 | void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); |
62 | struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct | 60 | struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct |
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README index 338377f7093b..b55badef4660 100644 --- a/drivers/net/wireless/mwifiex/README +++ b/drivers/net/wireless/mwifiex/README | |||
@@ -157,7 +157,7 @@ info | |||
157 | mp_wr_bitmap = <SDIO multi-port write bitmap> | 157 | mp_wr_bitmap = <SDIO multi-port write bitmap> |
158 | cmd_resp_received = <0/1, no cmd response to process/response received and yet to process> | 158 | cmd_resp_received = <0/1, no cmd response to process/response received and yet to process> |
159 | event_received = <0/1, no event to process/event received and yet to process> | 159 | event_received = <0/1, no event to process/event received and yet to process> |
160 | ioctl_pending = <number of ioctl pending> | 160 | cmd_pending = <number of cmd pending> |
161 | tx_pending = <number of Tx packet pending> | 161 | tx_pending = <number of Tx packet pending> |
162 | rx_pending = <number of Rx packet pending> | 162 | rx_pending = <number of Rx packet pending> |
163 | 163 | ||
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ec0895f4e8d3..74b6cf20da04 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -139,8 +139,16 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, | |||
139 | { | 139 | { |
140 | int ret = 0; | 140 | int ret = 0; |
141 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 141 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
142 | struct mwifiex_power_cfg power_cfg; | ||
142 | 143 | ||
143 | ret = mwifiex_set_tx_power(priv, type, dbm); | 144 | if (type == NL80211_TX_POWER_FIXED) { |
145 | power_cfg.is_power_auto = 0; | ||
146 | power_cfg.power_level = dbm; | ||
147 | } else { | ||
148 | power_cfg.is_power_auto = 1; | ||
149 | } | ||
150 | |||
151 | ret = mwifiex_set_tx_power(priv, &power_cfg); | ||
144 | 152 | ||
145 | return ret; | 153 | return ret; |
146 | } | 154 | } |
@@ -157,13 +165,15 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
157 | { | 165 | { |
158 | int ret = 0; | 166 | int ret = 0; |
159 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 167 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
168 | u32 ps_mode; | ||
160 | 169 | ||
161 | if (timeout) | 170 | if (timeout) |
162 | wiphy_dbg(wiphy, | 171 | wiphy_dbg(wiphy, |
163 | "info: ignoring the timeout value" | 172 | "info: ignoring the timeout value" |
164 | " for IEEE power save\n"); | 173 | " for IEEE power save\n"); |
165 | 174 | ||
166 | ret = mwifiex_drv_set_power(priv, enabled); | 175 | ps_mode = enabled; |
176 | ret = mwifiex_drv_set_power(priv, &ps_mode); | ||
167 | 177 | ||
168 | return ret; | 178 | return ret; |
169 | } | 179 | } |
@@ -291,8 +301,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
291 | 301 | ||
292 | domain_info->no_of_triplet = no_of_triplet; | 302 | domain_info->no_of_triplet = no_of_triplet; |
293 | /* Send cmd to FW to set domain info */ | 303 | /* Send cmd to FW to set domain info */ |
294 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, | 304 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, |
295 | HostCmd_ACT_GEN_SET, 0, NULL, NULL); | 305 | HostCmd_ACT_GEN_SET, 0, NULL); |
296 | if (ret) | 306 | if (ret) |
297 | wiphy_err(wiphy, "11D: setting domain info in FW\n"); | 307 | wiphy_err(wiphy, "11D: setting domain info in FW\n"); |
298 | 308 | ||
@@ -347,7 +357,6 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
347 | { | 357 | { |
348 | struct mwifiex_chan_freq_power cfp; | 358 | struct mwifiex_chan_freq_power cfp; |
349 | int ret = 0; | 359 | int ret = 0; |
350 | int status = 0; | ||
351 | struct mwifiex_ds_band_cfg band_cfg; | 360 | struct mwifiex_ds_band_cfg band_cfg; |
352 | u32 config_bands = 0; | 361 | u32 config_bands = 0; |
353 | struct wiphy *wiphy = priv->wdev->wiphy; | 362 | struct wiphy *wiphy = priv->wdev->wiphy; |
@@ -370,10 +379,9 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
370 | band_cfg.sec_chan_offset = | 379 | band_cfg.sec_chan_offset = |
371 | mwifiex_cfg80211_channel_type_to_mwifiex_channels | 380 | mwifiex_cfg80211_channel_type_to_mwifiex_channels |
372 | (channel_type); | 381 | (channel_type); |
373 | status = mwifiex_radio_ioctl_band_cfg(priv, HostCmd_ACT_GEN_SET, | 382 | ret = mwifiex_set_radio_band_cfg(priv, &band_cfg); |
374 | &band_cfg); | ||
375 | 383 | ||
376 | if (status) | 384 | if (ret) |
377 | return -EFAULT; | 385 | return -EFAULT; |
378 | mwifiex_send_domain_info_cmd_fw(wiphy); | 386 | mwifiex_send_domain_info_cmd_fw(wiphy); |
379 | } | 387 | } |
@@ -389,8 +397,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
389 | /* Convert frequency to channel */ | 397 | /* Convert frequency to channel */ |
390 | cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); | 398 | cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); |
391 | 399 | ||
392 | status = mwifiex_bss_ioctl_channel(priv, HostCmd_ACT_GEN_SET, &cfp); | 400 | ret = mwifiex_bss_set_channel(priv, &cfp); |
393 | if (status) | 401 | if (ret) |
394 | return -EFAULT; | 402 | return -EFAULT; |
395 | 403 | ||
396 | ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel); | 404 | ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel); |
@@ -422,66 +430,45 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, | |||
422 | /* | 430 | /* |
423 | * This function sets the fragmentation threshold. | 431 | * This function sets the fragmentation threshold. |
424 | * | 432 | * |
425 | * This function creates an IOCTL request, populates it accordingly | 433 | * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE |
426 | * and issues an IOCTL. | ||
427 | * | ||
428 | * The fragmentation threshold value must lies between MWIFIEX_FRAG_MIN_VALUE | ||
429 | * and MWIFIEX_FRAG_MAX_VALUE. | 434 | * and MWIFIEX_FRAG_MAX_VALUE. |
430 | */ | 435 | */ |
431 | static int | 436 | static int |
432 | mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) | 437 | mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) |
433 | { | 438 | { |
434 | int ret = 0; | 439 | int ret = 0; |
435 | int status = 0; | ||
436 | struct mwifiex_wait_queue *wait = NULL; | ||
437 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
438 | 440 | ||
439 | if (frag_thr < MWIFIEX_FRAG_MIN_VALUE | 441 | if (frag_thr < MWIFIEX_FRAG_MIN_VALUE |
440 | || frag_thr > MWIFIEX_FRAG_MAX_VALUE) | 442 | || frag_thr > MWIFIEX_FRAG_MAX_VALUE) |
441 | return -EINVAL; | 443 | return -EINVAL; |
442 | 444 | ||
443 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | 445 | /* Send request to firmware */ |
444 | if (!wait) | 446 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, |
445 | return -ENOMEM; | 447 | HostCmd_ACT_GEN_SET, FRAG_THRESH_I, |
446 | 448 | &frag_thr); | |
447 | status = mwifiex_snmp_mib_ioctl(priv, wait, FRAG_THRESH_I, | ||
448 | HostCmd_ACT_GEN_SET, &frag_thr); | ||
449 | |||
450 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) | ||
451 | ret = -EFAULT; | ||
452 | 449 | ||
453 | kfree(wait); | ||
454 | return ret; | 450 | return ret; |
455 | } | 451 | } |
456 | 452 | ||
457 | /* | 453 | /* |
458 | * This function sets the RTS threshold. | 454 | * This function sets the RTS threshold. |
459 | * | 455 | |
460 | * This function creates an IOCTL request, populates it accordingly | 456 | * The rts value must lie between MWIFIEX_RTS_MIN_VALUE |
461 | * and issues an IOCTL. | 457 | * and MWIFIEX_RTS_MAX_VALUE. |
462 | */ | 458 | */ |
463 | static int | 459 | static int |
464 | mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) | 460 | mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) |
465 | { | 461 | { |
466 | int ret = 0; | 462 | int ret = 0; |
467 | struct mwifiex_wait_queue *wait = NULL; | ||
468 | int status = 0; | ||
469 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
470 | 463 | ||
471 | if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) | 464 | if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) |
472 | rts_thr = MWIFIEX_RTS_MAX_VALUE; | 465 | rts_thr = MWIFIEX_RTS_MAX_VALUE; |
473 | 466 | ||
474 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | 467 | /* Send request to firmware */ |
475 | if (!wait) | 468 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, |
476 | return -ENOMEM; | 469 | HostCmd_ACT_GEN_SET, RTS_THRESH_I, |
470 | &rts_thr); | ||
477 | 471 | ||
478 | status = mwifiex_snmp_mib_ioctl(priv, wait, RTS_THRESH_I, | ||
479 | HostCmd_ACT_GEN_SET, &rts_thr); | ||
480 | |||
481 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) | ||
482 | ret = -EFAULT; | ||
483 | |||
484 | kfree(wait); | ||
485 | return ret; | 472 | return ret; |
486 | } | 473 | } |
487 | 474 | ||
@@ -518,7 +505,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, | |||
518 | { | 505 | { |
519 | int ret = 0; | 506 | int ret = 0; |
520 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 507 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
521 | struct mwifiex_wait_queue *wait = NULL; | ||
522 | 508 | ||
523 | if (priv->bss_mode == type) { | 509 | if (priv->bss_mode == type) { |
524 | wiphy_warn(wiphy, "already set to required type\n"); | 510 | wiphy_warn(wiphy, "already set to required type\n"); |
@@ -545,24 +531,13 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, | |||
545 | return -EINVAL; | 531 | return -EINVAL; |
546 | } | 532 | } |
547 | 533 | ||
548 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | 534 | mwifiex_deauthenticate(priv, NULL); |
549 | if (!wait) | ||
550 | return -ENOMEM; | ||
551 | |||
552 | mwifiex_deauthenticate(priv, wait, NULL); | ||
553 | 535 | ||
554 | priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; | 536 | priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; |
555 | 537 | ||
556 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, | 538 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, |
557 | HostCmd_ACT_GEN_SET, 0, wait, NULL); | 539 | HostCmd_ACT_GEN_SET, 0, NULL); |
558 | if (!ret) | ||
559 | ret = -EINPROGRESS; | ||
560 | 540 | ||
561 | ret = mwifiex_request_ioctl(priv, wait, ret, MWIFIEX_IOCTL_WAIT); | ||
562 | if (ret) | ||
563 | ret = -EFAULT; | ||
564 | |||
565 | kfree(wait); | ||
566 | return ret; | 541 | return ret; |
567 | } | 542 | } |
568 | 543 | ||
@@ -592,7 +567,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, | |||
592 | 567 | ||
593 | /* Get signal information from the firmware */ | 568 | /* Get signal information from the firmware */ |
594 | memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); | 569 | memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); |
595 | if (mwifiex_get_signal_info(priv, MWIFIEX_IOCTL_WAIT, &signal)) { | 570 | if (mwifiex_get_signal_info(priv, &signal)) { |
596 | dev_err(priv->adapter->dev, "getting signal information\n"); | 571 | dev_err(priv->adapter->dev, "getting signal information\n"); |
597 | ret = -EFAULT; | 572 | ret = -EFAULT; |
598 | } | 573 | } |
@@ -750,7 +725,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, | |||
750 | return -EBUSY; | 725 | return -EBUSY; |
751 | 726 | ||
752 | priv->disconnect = 1; | 727 | priv->disconnect = 1; |
753 | if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) | 728 | if (mwifiex_deauthenticate(priv, NULL)) |
754 | return -EFAULT; | 729 | return -EFAULT; |
755 | 730 | ||
756 | wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" | 731 | wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" |
@@ -838,8 +813,8 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, | |||
838 | u8 element_id, element_len; | 813 | u8 element_id, element_len; |
839 | 814 | ||
840 | memset(&scan_resp, 0, sizeof(scan_resp)); | 815 | memset(&scan_resp, 0, sizeof(scan_resp)); |
841 | if (mwifiex_get_scan_table(priv, MWIFIEX_IOCTL_WAIT, &scan_resp)) | 816 | scan_resp.scan_table = (u8 *) priv->adapter->scan_table; |
842 | return -EFAULT; | 817 | scan_resp.num_in_scan_table = priv->adapter->num_in_scan_table; |
843 | 818 | ||
844 | #define MAX_IE_BUF 2048 | 819 | #define MAX_IE_BUF 2048 |
845 | ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); | 820 | ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); |
@@ -986,7 +961,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
986 | } | 961 | } |
987 | 962 | ||
988 | /* disconnect before try to associate */ | 963 | /* disconnect before try to associate */ |
989 | mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL); | 964 | mwifiex_deauthenticate(priv, NULL); |
990 | 965 | ||
991 | if (channel) | 966 | if (channel) |
992 | ret = mwifiex_set_rf_channel(priv, channel, | 967 | ret = mwifiex_set_rf_channel(priv, channel, |
@@ -1046,7 +1021,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
1046 | } | 1021 | } |
1047 | done: | 1022 | done: |
1048 | /* Do specific SSID scanning */ | 1023 | /* Do specific SSID scanning */ |
1049 | if (mwifiex_request_scan(priv, MWIFIEX_IOCTL_WAIT, &req_ssid)) { | 1024 | if (mwifiex_request_scan(priv, &req_ssid)) { |
1050 | dev_err(priv->adapter->dev, "scan error\n"); | 1025 | dev_err(priv->adapter->dev, "scan error\n"); |
1051 | return -EFAULT; | 1026 | return -EFAULT; |
1052 | } | 1027 | } |
@@ -1055,8 +1030,7 @@ done: | |||
1055 | memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); | 1030 | memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); |
1056 | 1031 | ||
1057 | if (mode != NL80211_IFTYPE_ADHOC) { | 1032 | if (mode != NL80211_IFTYPE_ADHOC) { |
1058 | if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT, | 1033 | if (mwifiex_find_best_bss(priv, &ssid_bssid)) |
1059 | &ssid_bssid)) | ||
1060 | return -EFAULT; | 1034 | return -EFAULT; |
1061 | /* Inform the BSS information to kernel, otherwise | 1035 | /* Inform the BSS information to kernel, otherwise |
1062 | * kernel will give a panic after successful assoc */ | 1036 | * kernel will give a panic after successful assoc */ |
@@ -1072,7 +1046,10 @@ done: | |||
1072 | /* Connect to BSS by ESSID */ | 1046 | /* Connect to BSS by ESSID */ |
1073 | memset(&ssid_bssid.bssid, 0, ETH_ALEN); | 1047 | memset(&ssid_bssid.bssid, 0, ETH_ALEN); |
1074 | 1048 | ||
1075 | if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) | 1049 | if (!netif_queue_stopped(priv->netdev)) |
1050 | netif_stop_queue(priv->netdev); | ||
1051 | |||
1052 | if (mwifiex_bss_start(priv, &ssid_bssid)) | ||
1076 | return -EFAULT; | 1053 | return -EFAULT; |
1077 | 1054 | ||
1078 | if (mode == NL80211_IFTYPE_ADHOC) { | 1055 | if (mode == NL80211_IFTYPE_ADHOC) { |
@@ -1176,7 +1153,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | |||
1176 | 1153 | ||
1177 | wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", | 1154 | wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", |
1178 | priv->cfg_bssid); | 1155 | priv->cfg_bssid); |
1179 | if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) | 1156 | if (mwifiex_deauthenticate(priv, NULL)) |
1180 | return -EFAULT; | 1157 | return -EFAULT; |
1181 | 1158 | ||
1182 | queue_work(priv->workqueue, &priv->cfg_workqueue); | 1159 | queue_work(priv->workqueue, &priv->cfg_workqueue); |
@@ -1451,6 +1428,4 @@ done: | |||
1451 | memset(priv->cfg_bssid, 0, ETH_ALEN); | 1428 | memset(priv->cfg_bssid, 0, ETH_ALEN); |
1452 | priv->disconnect = 0; | 1429 | priv->disconnect = 0; |
1453 | } | 1430 | } |
1454 | |||
1455 | return; | ||
1456 | } | 1431 | } |
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 07187a405fee..bb73cfe14aeb 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c | |||
@@ -75,8 +75,7 @@ u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 }; | |||
75 | * This function maps an index in supported rates table into | 75 | * This function maps an index in supported rates table into |
76 | * the corresponding data rate. | 76 | * the corresponding data rate. |
77 | */ | 77 | */ |
78 | u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, | 78 | u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info) |
79 | u8 ht_info) | ||
80 | { | 79 | { |
81 | u16 mcs_rate[4][8] = { | 80 | u16 mcs_rate[4][8] = { |
82 | {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e} | 81 | {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e} |
@@ -126,7 +125,7 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, | |||
126 | * This function maps a data rate value into corresponding index in supported | 125 | * This function maps a data rate value into corresponding index in supported |
127 | * rates table. | 126 | * rates table. |
128 | */ | 127 | */ |
129 | u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate) | 128 | u8 mwifiex_data_rate_to_index(u32 rate) |
130 | { | 129 | { |
131 | u16 *ptr; | 130 | u16 *ptr; |
132 | 131 | ||
@@ -265,9 +264,7 @@ mwifiex_is_rate_auto(struct mwifiex_private *priv) | |||
265 | /* | 264 | /* |
266 | * This function converts rate bitmap into rate index. | 265 | * This function converts rate bitmap into rate index. |
267 | */ | 266 | */ |
268 | int | 267 | int mwifiex_get_rate_index(u16 *rate_bitmap, int size) |
269 | mwifiex_get_rate_index(struct mwifiex_adapter *adapter, u16 *rate_bitmap, | ||
270 | int size) | ||
271 | { | 268 | { |
272 | int i; | 269 | int i; |
273 | 270 | ||
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index a9aeb31af455..776146a104ec 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -36,11 +36,12 @@ | |||
36 | static void | 36 | static void |
37 | mwifiex_init_cmd_node(struct mwifiex_private *priv, | 37 | mwifiex_init_cmd_node(struct mwifiex_private *priv, |
38 | struct cmd_ctrl_node *cmd_node, | 38 | struct cmd_ctrl_node *cmd_node, |
39 | u32 cmd_oid, void *wait_queue, void *data_buf) | 39 | u32 cmd_oid, void *data_buf) |
40 | { | 40 | { |
41 | cmd_node->priv = priv; | 41 | cmd_node->priv = priv; |
42 | cmd_node->cmd_oid = cmd_oid; | 42 | cmd_node->cmd_oid = cmd_oid; |
43 | cmd_node->wq_buf = wait_queue; | 43 | cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; |
44 | priv->adapter->cmd_wait_q_required = false; | ||
44 | cmd_node->data_buf = data_buf; | 45 | cmd_node->data_buf = data_buf; |
45 | cmd_node->cmd_skb = cmd_node->skb; | 46 | cmd_node->cmd_skb = cmd_node->skb; |
46 | } | 47 | } |
@@ -86,39 +87,13 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, | |||
86 | { | 87 | { |
87 | cmd_node->cmd_oid = 0; | 88 | cmd_node->cmd_oid = 0; |
88 | cmd_node->cmd_flag = 0; | 89 | cmd_node->cmd_flag = 0; |
89 | cmd_node->wq_buf = NULL; | ||
90 | cmd_node->data_buf = NULL; | 90 | cmd_node->data_buf = NULL; |
91 | cmd_node->wait_q_enabled = false; | ||
91 | 92 | ||
92 | if (cmd_node->resp_skb) { | 93 | if (cmd_node->resp_skb) { |
93 | mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); | 94 | mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); |
94 | cmd_node->resp_skb = NULL; | 95 | cmd_node->resp_skb = NULL; |
95 | } | 96 | } |
96 | |||
97 | return; | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * This function returns a command node from the pending queue which | ||
102 | * matches the given IOCTL request. | ||
103 | */ | ||
104 | static struct cmd_ctrl_node * | ||
105 | mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter, | ||
106 | struct mwifiex_wait_queue *wait_queue) | ||
107 | { | ||
108 | unsigned long flags; | ||
109 | struct cmd_ctrl_node *cmd_node; | ||
110 | |||
111 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); | ||
112 | list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) { | ||
113 | if (cmd_node->wq_buf == wait_queue) { | ||
114 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, | ||
115 | flags); | ||
116 | return cmd_node; | ||
117 | } | ||
118 | } | ||
119 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); | ||
120 | |||
121 | return NULL; | ||
122 | } | 97 | } |
123 | 98 | ||
124 | /* | 99 | /* |
@@ -155,7 +130,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
155 | struct mwifiex_adapter *adapter = priv->adapter; | 130 | struct mwifiex_adapter *adapter = priv->adapter; |
156 | int ret = 0; | 131 | int ret = 0; |
157 | struct host_cmd_ds_command *host_cmd; | 132 | struct host_cmd_ds_command *host_cmd; |
158 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
159 | uint16_t cmd_code; | 133 | uint16_t cmd_code; |
160 | uint16_t cmd_size; | 134 | uint16_t cmd_size; |
161 | struct timeval tstamp; | 135 | struct timeval tstamp; |
@@ -165,15 +139,13 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
165 | return -1; | 139 | return -1; |
166 | 140 | ||
167 | host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); | 141 | host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); |
168 | if (cmd_node->wq_buf) | ||
169 | wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; | ||
170 | 142 | ||
171 | /* Sanity test */ | 143 | /* Sanity test */ |
172 | if (host_cmd == NULL || host_cmd->size == 0) { | 144 | if (host_cmd == NULL || host_cmd->size == 0) { |
173 | dev_err(adapter->dev, "DNLD_CMD: host_cmd is null" | 145 | dev_err(adapter->dev, "DNLD_CMD: host_cmd is null" |
174 | " or cmd size is 0, not sending\n"); | 146 | " or cmd size is 0, not sending\n"); |
175 | if (wait_queue) | 147 | if (cmd_node->wait_q_enabled) |
176 | wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; | 148 | adapter->cmd_wait_q.status = -1; |
177 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 149 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
178 | return -1; | 150 | return -1; |
179 | } | 151 | } |
@@ -206,10 +178,12 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
206 | cmd_node->cmd_skb->data, | 178 | cmd_node->cmd_skb->data, |
207 | cmd_node->cmd_skb->len, NULL); | 179 | cmd_node->cmd_skb->len, NULL); |
208 | 180 | ||
181 | skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN); | ||
182 | |||
209 | if (ret == -1) { | 183 | if (ret == -1) { |
210 | dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); | 184 | dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); |
211 | if (wait_queue) | 185 | if (cmd_node->wait_q_enabled) |
212 | wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; | 186 | adapter->cmd_wait_q.status = -1; |
213 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 187 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
214 | 188 | ||
215 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 189 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
@@ -435,7 +409,31 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) | |||
435 | } | 409 | } |
436 | 410 | ||
437 | /* | 411 | /* |
438 | * This function prepares a command before sending it to the firmware. | 412 | * This function is used to send synchronous command to the firmware. |
413 | * | ||
414 | * it allocates a wait queue for the command and wait for the command | ||
415 | * response. | ||
416 | */ | ||
417 | int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, | ||
418 | u16 cmd_action, u32 cmd_oid, void *data_buf) | ||
419 | { | ||
420 | int ret = 0; | ||
421 | struct mwifiex_adapter *adapter = priv->adapter; | ||
422 | |||
423 | adapter->cmd_wait_q_required = true; | ||
424 | adapter->cmd_wait_q.condition = false; | ||
425 | |||
426 | ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, | ||
427 | data_buf); | ||
428 | if (!ret) | ||
429 | ret = mwifiex_wait_queue_complete(adapter); | ||
430 | |||
431 | return ret; | ||
432 | } | ||
433 | |||
434 | |||
435 | /* | ||
436 | * This function prepares a command and asynchronously send it to the firmware. | ||
439 | * | 437 | * |
440 | * Preparation includes - | 438 | * Preparation includes - |
441 | * - Sanity tests to make sure the card is still present or the FW | 439 | * - Sanity tests to make sure the card is still present or the FW |
@@ -445,9 +443,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) | |||
445 | * - Fill up the non-default parameters and buffer pointers | 443 | * - Fill up the non-default parameters and buffer pointers |
446 | * - Add the command to pending queue | 444 | * - Add the command to pending queue |
447 | */ | 445 | */ |
448 | int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | 446 | int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, |
449 | u16 cmd_action, u32 cmd_oid, | 447 | u16 cmd_action, u32 cmd_oid, void *data_buf) |
450 | void *wait_queue, void *data_buf) | ||
451 | { | 448 | { |
452 | int ret = 0; | 449 | int ret = 0; |
453 | struct mwifiex_adapter *adapter = priv->adapter; | 450 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -485,7 +482,7 @@ int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
485 | } | 482 | } |
486 | 483 | ||
487 | /* Initialize the command node */ | 484 | /* Initialize the command node */ |
488 | mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, wait_queue, data_buf); | 485 | mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf); |
489 | 486 | ||
490 | if (!cmd_node->cmd_skb) { | 487 | if (!cmd_node->cmd_skb) { |
491 | dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); | 488 | dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); |
@@ -535,18 +532,13 @@ void | |||
535 | mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, | 532 | mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, |
536 | struct cmd_ctrl_node *cmd_node) | 533 | struct cmd_ctrl_node *cmd_node) |
537 | { | 534 | { |
538 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
539 | unsigned long flags; | 535 | unsigned long flags; |
540 | 536 | ||
541 | if (cmd_node == NULL) | 537 | if (!cmd_node) |
542 | return; | 538 | return; |
543 | if (cmd_node->wq_buf) { | 539 | |
544 | wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; | 540 | if (cmd_node->wait_q_enabled) |
545 | if (wait_queue->status != MWIFIEX_ERROR_NO_ERROR) | 541 | mwifiex_complete_cmd(adapter); |
546 | mwifiex_ioctl_complete(adapter, wait_queue, -1); | ||
547 | else | ||
548 | mwifiex_ioctl_complete(adapter, wait_queue, 0); | ||
549 | } | ||
550 | /* Clean the node */ | 542 | /* Clean the node */ |
551 | mwifiex_clean_cmd_node(adapter, cmd_node); | 543 | mwifiex_clean_cmd_node(adapter, cmd_node); |
552 | 544 | ||
@@ -554,8 +546,6 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, | |||
554 | spin_lock_irqsave(&adapter->cmd_free_q_lock, flags); | 546 | spin_lock_irqsave(&adapter->cmd_free_q_lock, flags); |
555 | list_add_tail(&cmd_node->list, &adapter->cmd_free_q); | 547 | list_add_tail(&cmd_node->list, &adapter->cmd_free_q); |
556 | spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); | 548 | spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); |
557 | |||
558 | return; | ||
559 | } | 549 | } |
560 | 550 | ||
561 | /* | 551 | /* |
@@ -600,8 +590,6 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, | |||
600 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); | 590 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); |
601 | 591 | ||
602 | dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command); | 592 | dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command); |
603 | |||
604 | return; | ||
605 | } | 593 | } |
606 | 594 | ||
607 | /* | 595 | /* |
@@ -692,7 +680,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
692 | uint16_t orig_cmdresp_no; | 680 | uint16_t orig_cmdresp_no; |
693 | uint16_t cmdresp_no; | 681 | uint16_t cmdresp_no; |
694 | uint16_t cmdresp_result; | 682 | uint16_t cmdresp_result; |
695 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
696 | struct timeval tstamp; | 683 | struct timeval tstamp; |
697 | unsigned long flags; | 684 | unsigned long flags; |
698 | 685 | ||
@@ -706,10 +693,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
706 | return -1; | 693 | return -1; |
707 | } | 694 | } |
708 | 695 | ||
709 | if (adapter->curr_cmd->wq_buf) | ||
710 | wait_queue = (struct mwifiex_wait_queue *) | ||
711 | adapter->curr_cmd->wq_buf; | ||
712 | |||
713 | adapter->num_cmd_timeout = 0; | 696 | adapter->num_cmd_timeout = 0; |
714 | 697 | ||
715 | resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; | 698 | resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; |
@@ -764,8 +747,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
764 | 747 | ||
765 | if (!(orig_cmdresp_no & HostCmd_RET_BIT)) { | 748 | if (!(orig_cmdresp_no & HostCmd_RET_BIT)) { |
766 | dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n"); | 749 | dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n"); |
767 | if (wait_queue) | 750 | if (adapter->curr_cmd->wait_q_enabled) |
768 | wait_queue->status = MWIFIEX_ERROR_FW_CMDRESP; | 751 | adapter->cmd_wait_q.status = -1; |
769 | 752 | ||
770 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 753 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
771 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 754 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
@@ -781,8 +764,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
781 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); | 764 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); |
782 | } else { | 765 | } else { |
783 | /* handle response */ | 766 | /* handle response */ |
784 | ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp, | 767 | ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp); |
785 | wait_queue); | ||
786 | } | 768 | } |
787 | 769 | ||
788 | /* Check init command response */ | 770 | /* Check init command response */ |
@@ -797,10 +779,10 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
797 | } | 779 | } |
798 | 780 | ||
799 | if (adapter->curr_cmd) { | 781 | if (adapter->curr_cmd) { |
800 | if (wait_queue && (!ret)) | 782 | if (adapter->curr_cmd->wait_q_enabled && (!ret)) |
801 | wait_queue->status = MWIFIEX_ERROR_NO_ERROR; | 783 | adapter->cmd_wait_q.status = 0; |
802 | else if (wait_queue && (ret == -1)) | 784 | else if (adapter->curr_cmd->wait_q_enabled && (ret == -1)) |
803 | wait_queue->status = MWIFIEX_ERROR_CMD_RESP_FAIL; | 785 | adapter->cmd_wait_q.status = -1; |
804 | 786 | ||
805 | /* Clean up and put current command back to cmd_free_q */ | 787 | /* Clean up and put current command back to cmd_free_q */ |
806 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 788 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
@@ -824,7 +806,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
824 | struct mwifiex_adapter *adapter = | 806 | struct mwifiex_adapter *adapter = |
825 | (struct mwifiex_adapter *) function_context; | 807 | (struct mwifiex_adapter *) function_context; |
826 | struct cmd_ctrl_node *cmd_node = NULL; | 808 | struct cmd_ctrl_node *cmd_node = NULL; |
827 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
828 | struct timeval tstamp; | 809 | struct timeval tstamp; |
829 | 810 | ||
830 | adapter->num_cmd_timeout++; | 811 | adapter->num_cmd_timeout++; |
@@ -834,10 +815,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
834 | return; | 815 | return; |
835 | } | 816 | } |
836 | cmd_node = adapter->curr_cmd; | 817 | cmd_node = adapter->curr_cmd; |
837 | if (cmd_node->wq_buf) { | 818 | if (cmd_node->wait_q_enabled) |
838 | wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; | 819 | adapter->cmd_wait_q.status = -ETIMEDOUT; |
839 | wait_queue->status = MWIFIEX_ERROR_CMD_TIMEOUT; | ||
840 | } | ||
841 | 820 | ||
842 | if (cmd_node) { | 821 | if (cmd_node) { |
843 | adapter->dbg.timeout_cmd_id = | 822 | adapter->dbg.timeout_cmd_id = |
@@ -886,8 +865,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
886 | } | 865 | } |
887 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) | 866 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) |
888 | mwifiex_init_fw_complete(adapter); | 867 | mwifiex_init_fw_complete(adapter); |
889 | |||
890 | return; | ||
891 | } | 868 | } |
892 | 869 | ||
893 | /* | 870 | /* |
@@ -901,18 +878,15 @@ void | |||
901 | mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | 878 | mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) |
902 | { | 879 | { |
903 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; | 880 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; |
904 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
905 | unsigned long flags; | 881 | unsigned long flags; |
906 | 882 | ||
907 | /* Cancel current cmd */ | 883 | /* Cancel current cmd */ |
908 | if ((adapter->curr_cmd) && (adapter->curr_cmd->wq_buf)) { | 884 | if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { |
909 | wait_queue = | ||
910 | (struct mwifiex_wait_queue *) adapter->curr_cmd->wq_buf; | ||
911 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 885 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
912 | adapter->curr_cmd->wq_buf = NULL; | 886 | adapter->curr_cmd->wait_q_enabled = false; |
913 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | 887 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
914 | wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; | 888 | adapter->cmd_wait_q.status = -1; |
915 | mwifiex_ioctl_complete(adapter, wait_queue, -1); | 889 | mwifiex_complete_cmd(adapter); |
916 | } | 890 | } |
917 | /* Cancel all pending command */ | 891 | /* Cancel all pending command */ |
918 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); | 892 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); |
@@ -921,12 +895,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | |||
921 | list_del(&cmd_node->list); | 895 | list_del(&cmd_node->list); |
922 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); | 896 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); |
923 | 897 | ||
924 | if (cmd_node->wq_buf) { | 898 | if (cmd_node->wait_q_enabled) { |
925 | wait_queue = | 899 | adapter->cmd_wait_q.status = -1; |
926 | (struct mwifiex_wait_queue *) cmd_node->wq_buf; | 900 | mwifiex_complete_cmd(adapter); |
927 | wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; | 901 | cmd_node->wait_q_enabled = false; |
928 | mwifiex_ioctl_complete(adapter, wait_queue, -1); | ||
929 | cmd_node->wq_buf = NULL; | ||
930 | } | 902 | } |
931 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 903 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
932 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); | 904 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); |
@@ -940,7 +912,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | |||
940 | list_del(&cmd_node->list); | 912 | list_del(&cmd_node->list); |
941 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | 913 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); |
942 | 914 | ||
943 | cmd_node->wq_buf = NULL; | 915 | cmd_node->wait_q_enabled = false; |
944 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 916 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
945 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 917 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
946 | } | 918 | } |
@@ -962,8 +934,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | |||
962 | * are cancelled. | 934 | * are cancelled. |
963 | */ | 935 | */ |
964 | void | 936 | void |
965 | mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, | 937 | mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) |
966 | struct mwifiex_wait_queue *wait_queue) | ||
967 | { | 938 | { |
968 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; | 939 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; |
969 | unsigned long cmd_flags; | 940 | unsigned long cmd_flags; |
@@ -972,45 +943,33 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, | |||
972 | uint16_t cancel_scan_cmd = false; | 943 | uint16_t cancel_scan_cmd = false; |
973 | 944 | ||
974 | if ((adapter->curr_cmd) && | 945 | if ((adapter->curr_cmd) && |
975 | (adapter->curr_cmd->wq_buf == wait_queue)) { | 946 | (adapter->curr_cmd->wait_q_enabled)) { |
976 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); | 947 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); |
977 | cmd_node = adapter->curr_cmd; | 948 | cmd_node = adapter->curr_cmd; |
978 | cmd_node->wq_buf = NULL; | 949 | cmd_node->wait_q_enabled = false; |
979 | cmd_node->cmd_flag |= CMD_F_CANCELED; | 950 | cmd_node->cmd_flag |= CMD_F_CANCELED; |
980 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); | ||
981 | } | ||
982 | |||
983 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); | ||
984 | while (1) { | ||
985 | cmd_node = mwifiex_get_pending_ioctl_cmd(adapter, wait_queue); | ||
986 | if (!cmd_node) | ||
987 | break; | ||
988 | |||
989 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, | 951 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, |
990 | cmd_pending_q_flags); | 952 | cmd_pending_q_flags); |
991 | list_del(&cmd_node->list); | 953 | list_del(&cmd_node->list); |
992 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, | 954 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, |
993 | cmd_pending_q_flags); | 955 | cmd_pending_q_flags); |
994 | |||
995 | cmd_node->wq_buf = NULL; | ||
996 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 956 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
957 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); | ||
997 | } | 958 | } |
998 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); | 959 | |
999 | /* Cancel all pending scan command */ | 960 | /* Cancel all pending scan command */ |
1000 | spin_lock_irqsave(&adapter->scan_pending_q_lock, | 961 | spin_lock_irqsave(&adapter->scan_pending_q_lock, |
1001 | scan_pending_q_flags); | 962 | scan_pending_q_flags); |
1002 | list_for_each_entry_safe(cmd_node, tmp_node, | 963 | list_for_each_entry_safe(cmd_node, tmp_node, |
1003 | &adapter->scan_pending_q, list) { | 964 | &adapter->scan_pending_q, list) { |
1004 | if (cmd_node->wq_buf == wait_queue) { | 965 | list_del(&cmd_node->list); |
1005 | list_del(&cmd_node->list); | 966 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
1006 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 967 | scan_pending_q_flags); |
1007 | scan_pending_q_flags); | 968 | cmd_node->wait_q_enabled = false; |
1008 | cmd_node->wq_buf = NULL; | 969 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
1009 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 970 | spin_lock_irqsave(&adapter->scan_pending_q_lock, |
1010 | spin_lock_irqsave(&adapter->scan_pending_q_lock, | 971 | scan_pending_q_flags); |
1011 | scan_pending_q_flags); | 972 | cancel_scan_cmd = true; |
1012 | cancel_scan_cmd = true; | ||
1013 | } | ||
1014 | } | 973 | } |
1015 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 974 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
1016 | scan_pending_q_flags); | 975 | scan_pending_q_flags); |
@@ -1020,10 +979,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, | |||
1020 | adapter->scan_processing = false; | 979 | adapter->scan_processing = false; |
1021 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); | 980 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); |
1022 | } | 981 | } |
1023 | wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; | 982 | adapter->cmd_wait_q.status = -1; |
1024 | mwifiex_ioctl_complete(adapter, wait_queue, -1); | 983 | mwifiex_complete_cmd(adapter); |
1025 | |||
1026 | return; | ||
1027 | } | 984 | } |
1028 | 985 | ||
1029 | /* | 986 | /* |
@@ -1127,7 +1084,6 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) | |||
1127 | adapter->is_hs_configured = false; | 1084 | adapter->is_hs_configured = false; |
1128 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, | 1085 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, |
1129 | MWIFIEX_BSS_ROLE_ANY), false); | 1086 | MWIFIEX_BSS_ROLE_ANY), false); |
1130 | return; | ||
1131 | } | 1087 | } |
1132 | 1088 | ||
1133 | /* | 1089 | /* |
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 63b09692f27d..7ddcb062f103 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c | |||
@@ -129,8 +129,8 @@ static struct mwifiex_debug_data items[] = { | |||
129 | item_addr(event_received), 1}, | 129 | item_addr(event_received), 1}, |
130 | 130 | ||
131 | /* variables defined in struct mwifiex_adapter */ | 131 | /* variables defined in struct mwifiex_adapter */ |
132 | {"ioctl_pending", adapter_item_size(ioctl_pending), | 132 | {"cmd_pending", adapter_item_size(cmd_pending), |
133 | adapter_item_addr(ioctl_pending), 1}, | 133 | adapter_item_addr(cmd_pending), 1}, |
134 | {"tx_pending", adapter_item_size(tx_pending), | 134 | {"tx_pending", adapter_item_size(tx_pending), |
135 | adapter_item_addr(tx_pending), 1}, | 135 | adapter_item_addr(tx_pending), 1}, |
136 | {"rx_pending", adapter_item_size(rx_pending), | 136 | {"rx_pending", adapter_item_size(rx_pending), |
@@ -735,8 +735,6 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv) | |||
735 | MWIFIEX_DFS_ADD_FILE(getlog); | 735 | MWIFIEX_DFS_ADD_FILE(getlog); |
736 | MWIFIEX_DFS_ADD_FILE(regrdwr); | 736 | MWIFIEX_DFS_ADD_FILE(regrdwr); |
737 | MWIFIEX_DFS_ADD_FILE(rdeeprom); | 737 | MWIFIEX_DFS_ADD_FILE(rdeeprom); |
738 | |||
739 | return; | ||
740 | } | 738 | } |
741 | 739 | ||
742 | /* | 740 | /* |
@@ -749,7 +747,6 @@ mwifiex_dev_debugfs_remove(struct mwifiex_private *priv) | |||
749 | return; | 747 | return; |
750 | 748 | ||
751 | debugfs_remove_recursive(priv->dfs_dev_dir); | 749 | debugfs_remove_recursive(priv->dfs_dev_dir); |
752 | return; | ||
753 | } | 750 | } |
754 | 751 | ||
755 | /* | 752 | /* |
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index c3c15f9e757e..8364b62c3298 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h | |||
@@ -61,23 +61,6 @@ | |||
61 | 61 | ||
62 | #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) | 62 | #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) |
63 | 63 | ||
64 | enum mwifiex_error_code { | ||
65 | MWIFIEX_ERROR_NO_ERROR = 0, | ||
66 | MWIFIEX_ERROR_FW_NOT_READY = 0x00000001, | ||
67 | MWIFIEX_ERROR_FW_BUSY, | ||
68 | MWIFIEX_ERROR_FW_CMDRESP, | ||
69 | MWIFIEX_ERROR_PKT_SIZE_INVALID = 0x80000001, | ||
70 | MWIFIEX_ERROR_PKT_TIMEOUT, | ||
71 | MWIFIEX_ERROR_CMD_INVALID, | ||
72 | MWIFIEX_ERROR_CMD_TIMEOUT, | ||
73 | MWIFIEX_ERROR_CMD_DNLD_FAIL, | ||
74 | MWIFIEX_ERROR_CMD_CANCEL, | ||
75 | MWIFIEX_ERROR_CMD_RESP_FAIL, | ||
76 | MWIFIEX_ERROR_ASSOC_FAIL, | ||
77 | MWIFIEX_ERROR_EVENT_UNKNOWN, | ||
78 | MWIFIEX_ERROR_INVALID_PARAMETER, | ||
79 | }; | ||
80 | |||
81 | enum mwifiex_bss_type { | 64 | enum mwifiex_bss_type { |
82 | MWIFIEX_BSS_TYPE_STA = 0, | 65 | MWIFIEX_BSS_TYPE_STA = 0, |
83 | MWIFIEX_BSS_TYPE_UAP = 1, | 66 | MWIFIEX_BSS_TYPE_UAP = 1, |
@@ -112,12 +95,9 @@ struct mwifiex_802_11_ssid { | |||
112 | }; | 95 | }; |
113 | 96 | ||
114 | struct mwifiex_wait_queue { | 97 | struct mwifiex_wait_queue { |
115 | u32 bss_index; | 98 | wait_queue_head_t wait; |
116 | wait_queue_head_t *wait; | 99 | u16 condition; |
117 | u16 *condition; | ||
118 | u32 start_time; | ||
119 | int status; | 100 | int status; |
120 | u32 enabled; | ||
121 | }; | 101 | }; |
122 | 102 | ||
123 | struct mwifiex_rxinfo { | 103 | struct mwifiex_rxinfo { |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 2b938115b26a..f8c008f8f476 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -72,33 +72,12 @@ enum KEY_TYPE_ID { | |||
72 | KEY_TYPE_ID_AES, | 72 | KEY_TYPE_ID_AES, |
73 | KEY_TYPE_ID_WAPI, | 73 | KEY_TYPE_ID_WAPI, |
74 | }; | 74 | }; |
75 | 75 | #define KEY_MCAST BIT(0) | |
76 | enum KEY_INFO_WEP { | 76 | #define KEY_UNICAST BIT(1) |
77 | KEY_INFO_WEP_MCAST = 0x01, | 77 | #define KEY_ENABLED BIT(2) |
78 | KEY_INFO_WEP_UNICAST = 0x02, | ||
79 | KEY_INFO_WEP_ENABLED = 0x04 | ||
80 | }; | ||
81 | |||
82 | enum KEY_INFO_TKIP { | ||
83 | KEY_INFO_TKIP_MCAST = 0x01, | ||
84 | KEY_INFO_TKIP_UNICAST = 0x02, | ||
85 | KEY_INFO_TKIP_ENABLED = 0x04 | ||
86 | }; | ||
87 | |||
88 | enum KEY_INFO_AES { | ||
89 | KEY_INFO_AES_MCAST = 0x01, | ||
90 | KEY_INFO_AES_UNICAST = 0x02, | ||
91 | KEY_INFO_AES_ENABLED = 0x04 | ||
92 | }; | ||
93 | 78 | ||
94 | #define WAPI_KEY_LEN 50 | 79 | #define WAPI_KEY_LEN 50 |
95 | 80 | ||
96 | enum KEY_INFO_WAPI { | ||
97 | KEY_INFO_WAPI_MCAST = 0x01, | ||
98 | KEY_INFO_WAPI_UNICAST = 0x02, | ||
99 | KEY_INFO_WAPI_ENABLED = 0x04 | ||
100 | }; | ||
101 | |||
102 | #define MAX_POLL_TRIES 100 | 81 | #define MAX_POLL_TRIES 100 |
103 | 82 | ||
104 | #define MAX_MULTI_INTERFACE_POLL_TRIES 1000 | 83 | #define MAX_MULTI_INTERFACE_POLL_TRIES 1000 |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 8189862da1f9..1b79a5ac9214 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -35,7 +35,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) | |||
35 | { | 35 | { |
36 | struct mwifiex_adapter *adapter = priv->adapter; | 36 | struct mwifiex_adapter *adapter = priv->adapter; |
37 | struct mwifiex_bss_prio_node *bss_prio; | 37 | struct mwifiex_bss_prio_node *bss_prio; |
38 | int status = 0; | ||
39 | unsigned long flags; | 38 | unsigned long flags; |
40 | 39 | ||
41 | bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); | 40 | bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); |
@@ -59,7 +58,7 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) | |||
59 | spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] | 58 | spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] |
60 | .bss_prio_lock, flags); | 59 | .bss_prio_lock, flags); |
61 | 60 | ||
62 | return status; | 61 | return 0; |
63 | } | 62 | } |
64 | 63 | ||
65 | /* | 64 | /* |
@@ -300,8 +299,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
300 | adapter->adhoc_awake_period = 0; | 299 | adapter->adhoc_awake_period = 0; |
301 | memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); | 300 | memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); |
302 | adapter->arp_filter_size = 0; | 301 | adapter->arp_filter_size = 0; |
303 | |||
304 | return; | ||
305 | } | 302 | } |
306 | 303 | ||
307 | /* | 304 | /* |
@@ -340,8 +337,6 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter) | |||
340 | adapter->if_ops.cleanup_if(adapter); | 337 | adapter->if_ops.cleanup_if(adapter); |
341 | 338 | ||
342 | dev_kfree_skb_any(adapter->sleep_cfm); | 339 | dev_kfree_skb_any(adapter->sleep_cfm); |
343 | |||
344 | return; | ||
345 | } | 340 | } |
346 | 341 | ||
347 | /* | 342 | /* |
@@ -429,8 +424,6 @@ void mwifiex_free_lock_list(struct mwifiex_adapter *adapter) | |||
429 | list_del(&priv->rx_reorder_tbl_ptr); | 424 | list_del(&priv->rx_reorder_tbl_ptr); |
430 | } | 425 | } |
431 | } | 426 | } |
432 | |||
433 | return; | ||
434 | } | 427 | } |
435 | 428 | ||
436 | /* | 429 | /* |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 7a9e0b5962ed..60d25c690c07 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -590,11 +590,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | |||
590 | * an association success (0) or failure (non-zero). | 590 | * an association success (0) or failure (non-zero). |
591 | */ | 591 | */ |
592 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | 592 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, |
593 | struct host_cmd_ds_command *resp, void *wq_buf) | 593 | struct host_cmd_ds_command *resp) |
594 | { | 594 | { |
595 | struct mwifiex_adapter *adapter = priv->adapter; | ||
595 | int ret = 0; | 596 | int ret = 0; |
596 | struct mwifiex_wait_queue *wait_queue = | ||
597 | (struct mwifiex_wait_queue *) wq_buf; | ||
598 | struct ieee_types_assoc_rsp *assoc_rsp; | 597 | struct ieee_types_assoc_rsp *assoc_rsp; |
599 | struct mwifiex_bssdescriptor *bss_desc; | 598 | struct mwifiex_bssdescriptor *bss_desc; |
600 | u8 enable_data = true; | 599 | u8 enable_data = true; |
@@ -718,16 +717,11 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
718 | 717 | ||
719 | done: | 718 | done: |
720 | /* Need to indicate IOCTL complete */ | 719 | /* Need to indicate IOCTL complete */ |
721 | if (wait_queue) { | 720 | if (adapter->curr_cmd->wait_q_enabled) { |
722 | if (ret) { | 721 | if (ret) |
723 | if (assoc_rsp->status_code) | 722 | adapter->cmd_wait_q.status = -1; |
724 | wait_queue->status = | 723 | else |
725 | le16_to_cpu(assoc_rsp->status_code); | 724 | adapter->cmd_wait_q.status = 0; |
726 | else | ||
727 | wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; | ||
728 | } else { | ||
729 | wait_queue->status = MWIFIEX_ERROR_NO_ERROR; | ||
730 | } | ||
731 | } | 725 | } |
732 | 726 | ||
733 | return ret; | 727 | return ret; |
@@ -885,9 +879,9 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
885 | mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); | 879 | mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); |
886 | if ((adapter->adhoc_start_band & BAND_G) && | 880 | if ((adapter->adhoc_start_band & BAND_G) && |
887 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { | 881 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { |
888 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, | 882 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
889 | HostCmd_ACT_GEN_SET, | 883 | HostCmd_ACT_GEN_SET, 0, |
890 | 0, NULL, &priv->curr_pkt_filter); | 884 | &priv->curr_pkt_filter); |
891 | 885 | ||
892 | if (ret) { | 886 | if (ret) { |
893 | dev_err(adapter->dev, | 887 | dev_err(adapter->dev, |
@@ -1066,9 +1060,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
1066 | priv-> | 1060 | priv-> |
1067 | curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; | 1061 | curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; |
1068 | 1062 | ||
1069 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, | 1063 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
1070 | HostCmd_ACT_GEN_SET, 0, NULL, | 1064 | HostCmd_ACT_GEN_SET, 0, |
1071 | &curr_pkt_filter); | 1065 | &curr_pkt_filter); |
1072 | if (ret) { | 1066 | if (ret) { |
1073 | dev_err(priv->adapter->dev, | 1067 | dev_err(priv->adapter->dev, |
1074 | "ADHOC_J_CMD: G Protection config failed\n"); | 1068 | "ADHOC_J_CMD: G Protection config failed\n"); |
@@ -1192,11 +1186,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
1192 | * saves the beacon buffer. | 1186 | * saves the beacon buffer. |
1193 | */ | 1187 | */ |
1194 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | 1188 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, |
1195 | struct host_cmd_ds_command *resp, void *wq_buf) | 1189 | struct host_cmd_ds_command *resp) |
1196 | { | 1190 | { |
1197 | int ret = 0; | 1191 | int ret = 0; |
1198 | struct mwifiex_wait_queue *wait_queue = | 1192 | struct mwifiex_adapter *adapter = priv->adapter; |
1199 | (struct mwifiex_wait_queue *) wq_buf; | ||
1200 | struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; | 1193 | struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; |
1201 | struct mwifiex_bssdescriptor *bss_desc; | 1194 | struct mwifiex_bssdescriptor *bss_desc; |
1202 | u16 command = le16_to_cpu(resp->command); | 1195 | u16 command = le16_to_cpu(resp->command); |
@@ -1264,11 +1257,11 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | |||
1264 | 1257 | ||
1265 | done: | 1258 | done: |
1266 | /* Need to indicate IOCTL complete */ | 1259 | /* Need to indicate IOCTL complete */ |
1267 | if (wait_queue) { | 1260 | if (adapter->curr_cmd->wait_q_enabled) { |
1268 | if (ret) | 1261 | if (ret) |
1269 | wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; | 1262 | adapter->cmd_wait_q.status = -1; |
1270 | else | 1263 | else |
1271 | wait_queue->status = MWIFIEX_ERROR_NO_ERROR; | 1264 | adapter->cmd_wait_q.status = 0; |
1272 | 1265 | ||
1273 | } | 1266 | } |
1274 | 1267 | ||
@@ -1283,7 +1276,7 @@ done: | |||
1283 | * command to firmware. | 1276 | * command to firmware. |
1284 | */ | 1277 | */ |
1285 | int mwifiex_associate(struct mwifiex_private *priv, | 1278 | int mwifiex_associate(struct mwifiex_private *priv, |
1286 | void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) | 1279 | struct mwifiex_bssdescriptor *bss_desc) |
1287 | { | 1280 | { |
1288 | int ret = 0; | 1281 | int ret = 0; |
1289 | u8 current_bssid[ETH_ALEN]; | 1282 | u8 current_bssid[ETH_ALEN]; |
@@ -1301,9 +1294,8 @@ int mwifiex_associate(struct mwifiex_private *priv, | |||
1301 | retrieval */ | 1294 | retrieval */ |
1302 | priv->assoc_rsp_size = 0; | 1295 | priv->assoc_rsp_size = 0; |
1303 | 1296 | ||
1304 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE, | 1297 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE, |
1305 | HostCmd_ACT_GEN_SET, 0, wait_queue, | 1298 | HostCmd_ACT_GEN_SET, 0, bss_desc); |
1306 | bss_desc); | ||
1307 | 1299 | ||
1308 | return ret; | 1300 | return ret; |
1309 | } | 1301 | } |
@@ -1315,7 +1307,7 @@ int mwifiex_associate(struct mwifiex_private *priv, | |||
1315 | */ | 1307 | */ |
1316 | int | 1308 | int |
1317 | mwifiex_adhoc_start(struct mwifiex_private *priv, | 1309 | mwifiex_adhoc_start(struct mwifiex_private *priv, |
1318 | void *wait_queue, struct mwifiex_802_11_ssid *adhoc_ssid) | 1310 | struct mwifiex_802_11_ssid *adhoc_ssid) |
1319 | { | 1311 | { |
1320 | int ret = 0; | 1312 | int ret = 0; |
1321 | 1313 | ||
@@ -1326,9 +1318,8 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, | |||
1326 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", | 1318 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", |
1327 | priv->curr_bss_params.band); | 1319 | priv->curr_bss_params.band); |
1328 | 1320 | ||
1329 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START, | 1321 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, |
1330 | HostCmd_ACT_GEN_SET, 0, wait_queue, | 1322 | HostCmd_ACT_GEN_SET, 0, adhoc_ssid); |
1331 | adhoc_ssid); | ||
1332 | 1323 | ||
1333 | return ret; | 1324 | return ret; |
1334 | } | 1325 | } |
@@ -1340,7 +1331,7 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, | |||
1340 | * if already not connected to the requested SSID. | 1331 | * if already not connected to the requested SSID. |
1341 | */ | 1332 | */ |
1342 | int mwifiex_adhoc_join(struct mwifiex_private *priv, | 1333 | int mwifiex_adhoc_join(struct mwifiex_private *priv, |
1343 | void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) | 1334 | struct mwifiex_bssdescriptor *bss_desc) |
1344 | { | 1335 | { |
1345 | int ret = 0; | 1336 | int ret = 0; |
1346 | 1337 | ||
@@ -1369,9 +1360,8 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, | |||
1369 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", | 1360 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", |
1370 | priv->curr_bss_params.band); | 1361 | priv->curr_bss_params.band); |
1371 | 1362 | ||
1372 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, | 1363 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, |
1373 | HostCmd_ACT_GEN_SET, 0, wait_queue, | 1364 | HostCmd_ACT_GEN_SET, 0, bss_desc); |
1374 | bss_desc); | ||
1375 | 1365 | ||
1376 | return ret; | 1366 | return ret; |
1377 | } | 1367 | } |
@@ -1380,9 +1370,7 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, | |||
1380 | * This function deauthenticates/disconnects from infra network by sending | 1370 | * This function deauthenticates/disconnects from infra network by sending |
1381 | * deauthentication request. | 1371 | * deauthentication request. |
1382 | */ | 1372 | */ |
1383 | static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, | 1373 | static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac) |
1384 | struct mwifiex_wait_queue *wait, | ||
1385 | u8 *mac) | ||
1386 | { | 1374 | { |
1387 | u8 mac_address[ETH_ALEN]; | 1375 | u8 mac_address[ETH_ALEN]; |
1388 | int ret = 0; | 1376 | int ret = 0; |
@@ -1400,11 +1388,8 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, | |||
1400 | bss_descriptor.mac_address, ETH_ALEN); | 1388 | bss_descriptor.mac_address, ETH_ALEN); |
1401 | } | 1389 | } |
1402 | 1390 | ||
1403 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, | 1391 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, |
1404 | HostCmd_ACT_GEN_SET, 0, wait, &mac_address); | 1392 | HostCmd_ACT_GEN_SET, 0, &mac_address); |
1405 | |||
1406 | if (!ret && wait) | ||
1407 | ret = -EINPROGRESS; | ||
1408 | 1393 | ||
1409 | return ret; | 1394 | return ret; |
1410 | } | 1395 | } |
@@ -1415,26 +1400,23 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, | |||
1415 | * In case of infra made, it sends deauthentication request, and | 1400 | * In case of infra made, it sends deauthentication request, and |
1416 | * in case of ad-hoc mode, a stop network request is sent to the firmware. | 1401 | * in case of ad-hoc mode, a stop network request is sent to the firmware. |
1417 | */ | 1402 | */ |
1418 | int mwifiex_deauthenticate(struct mwifiex_private *priv, | 1403 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac) |
1419 | struct mwifiex_wait_queue *wait, u8 *mac) | ||
1420 | { | 1404 | { |
1421 | int ret = 0; | 1405 | int ret = 0; |
1422 | 1406 | ||
1423 | if (priv->media_connected) { | 1407 | if (priv->media_connected) { |
1424 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 1408 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { |
1425 | ret = mwifiex_deauthenticate_infra(priv, wait, mac); | 1409 | ret = mwifiex_deauthenticate_infra(priv, mac); |
1426 | } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | 1410 | } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { |
1427 | ret = mwifiex_prepare_cmd(priv, | 1411 | ret = mwifiex_send_cmd_sync(priv, |
1428 | HostCmd_CMD_802_11_AD_HOC_STOP, | 1412 | HostCmd_CMD_802_11_AD_HOC_STOP, |
1429 | HostCmd_ACT_GEN_SET, 0, wait, NULL); | 1413 | HostCmd_ACT_GEN_SET, 0, NULL); |
1430 | |||
1431 | if (!ret && wait) | ||
1432 | ret = -EINPROGRESS; | ||
1433 | } | 1414 | } |
1434 | } | 1415 | } |
1435 | 1416 | ||
1436 | return ret; | 1417 | return ret; |
1437 | } | 1418 | } |
1419 | EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); | ||
1438 | 1420 | ||
1439 | /* | 1421 | /* |
1440 | * This function converts band to radio type used in channel TLV. | 1422 | * This function converts band to radio type used in channel TLV. |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index ed89ca41a902..77abfc3d6c32 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -505,7 +505,6 @@ mwifiex_fill_buffer(struct sk_buff *skb) | |||
505 | */ | 505 | */ |
506 | do_gettimeofday(&tv); | 506 | do_gettimeofday(&tv); |
507 | skb->tstamp = timeval_to_ktime(tv); | 507 | skb->tstamp = timeval_to_ktime(tv); |
508 | return; | ||
509 | } | 508 | } |
510 | 509 | ||
511 | /* | 510 | /* |
@@ -597,16 +596,23 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) | |||
597 | { | 596 | { |
598 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 597 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
599 | struct sockaddr *hw_addr = (struct sockaddr *) addr; | 598 | struct sockaddr *hw_addr = (struct sockaddr *) addr; |
599 | int ret = 0; | ||
600 | 600 | ||
601 | memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); | 601 | memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); |
602 | 602 | ||
603 | if (mwifiex_request_set_mac_address(priv)) { | 603 | /* Send request to firmware */ |
604 | dev_err(priv->adapter->dev, "set MAC address failed\n"); | 604 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS, |
605 | return -EFAULT; | 605 | HostCmd_ACT_GEN_SET, 0, NULL); |
606 | } | 606 | |
607 | if (!ret) | ||
608 | memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); | ||
609 | else | ||
610 | dev_err(priv->adapter->dev, "set mac address failed: ret=%d" | ||
611 | "\n", ret); | ||
612 | |||
607 | memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); | 613 | memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); |
608 | 614 | ||
609 | return 0; | 615 | return ret; |
610 | } | 616 | } |
611 | 617 | ||
612 | /* | 618 | /* |
@@ -615,7 +621,20 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) | |||
615 | static void mwifiex_set_multicast_list(struct net_device *dev) | 621 | static void mwifiex_set_multicast_list(struct net_device *dev) |
616 | { | 622 | { |
617 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 623 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
618 | mwifiex_request_set_multicast_list(priv, dev); | 624 | struct mwifiex_multicast_list mcast_list; |
625 | |||
626 | if (dev->flags & IFF_PROMISC) { | ||
627 | mcast_list.mode = MWIFIEX_PROMISC_MODE; | ||
628 | } else if (dev->flags & IFF_ALLMULTI || | ||
629 | netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) { | ||
630 | mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; | ||
631 | } else { | ||
632 | mcast_list.mode = MWIFIEX_MULTICAST_MODE; | ||
633 | if (netdev_mc_count(dev)) | ||
634 | mcast_list.num_multicast_addr = | ||
635 | mwifiex_copy_mcast_addr(&mcast_list, dev); | ||
636 | } | ||
637 | mwifiex_request_set_multicast_list(priv, &mcast_list); | ||
619 | } | 638 | } |
620 | 639 | ||
621 | /* | 640 | /* |
@@ -677,9 +696,6 @@ mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev) | |||
677 | { | 696 | { |
678 | dev->netdev_ops = &mwifiex_netdev_ops; | 697 | dev->netdev_ops = &mwifiex_netdev_ops; |
679 | /* Initialize private structure */ | 698 | /* Initialize private structure */ |
680 | init_waitqueue_head(&priv->ioctl_wait_q); | ||
681 | init_waitqueue_head(&priv->cmd_wait_q); | ||
682 | init_waitqueue_head(&priv->w_stats_wait_q); | ||
683 | priv->current_key_index = 0; | 699 | priv->current_key_index = 0; |
684 | priv->media_connected = false; | 700 | priv->media_connected = false; |
685 | memset(&priv->nick_name, 0, sizeof(priv->nick_name)); | 701 | memset(&priv->nick_name, 0, sizeof(priv->nick_name)); |
@@ -803,35 +819,7 @@ mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index) | |||
803 | wiphy_unregister(priv->wdev->wiphy); | 819 | wiphy_unregister(priv->wdev->wiphy); |
804 | wiphy_free(priv->wdev->wiphy); | 820 | wiphy_free(priv->wdev->wiphy); |
805 | kfree(priv->wdev); | 821 | kfree(priv->wdev); |
806 | |||
807 | return; | ||
808 | } | ||
809 | |||
810 | /* | ||
811 | * Sends IOCTL request to shutdown firmware. | ||
812 | * | ||
813 | * This function allocates the IOCTL request buffer, fills it | ||
814 | * with requisite parameters and calls the IOCTL handler. | ||
815 | */ | ||
816 | int mwifiex_shutdown_fw(struct mwifiex_private *priv, u8 wait_option) | ||
817 | { | ||
818 | struct mwifiex_wait_queue *wait = NULL; | ||
819 | int status = 0; | ||
820 | |||
821 | /* Allocate an IOCTL request buffer */ | ||
822 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
823 | if (!wait) | ||
824 | return -ENOMEM; | ||
825 | |||
826 | status = mwifiex_misc_ioctl_init_shutdown(priv->adapter, wait, | ||
827 | MWIFIEX_FUNC_SHUTDOWN); | ||
828 | |||
829 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
830 | |||
831 | kfree(wait); | ||
832 | return status; | ||
833 | } | 822 | } |
834 | EXPORT_SYMBOL_GPL(mwifiex_shutdown_fw); | ||
835 | 823 | ||
836 | /* | 824 | /* |
837 | * This function check if command is pending. | 825 | * This function check if command is pending. |
@@ -927,6 +915,10 @@ mwifiex_add_card(void *card, struct semaphore *sem, | |||
927 | adapter->is_suspended = false; | 915 | adapter->is_suspended = false; |
928 | adapter->hs_activated = false; | 916 | adapter->hs_activated = false; |
929 | init_waitqueue_head(&adapter->hs_activate_wait_q); | 917 | init_waitqueue_head(&adapter->hs_activate_wait_q); |
918 | adapter->cmd_wait_q_required = false; | ||
919 | init_waitqueue_head(&adapter->cmd_wait_q.wait); | ||
920 | adapter->cmd_wait_q.condition = false; | ||
921 | adapter->cmd_wait_q.status = 0; | ||
930 | 922 | ||
931 | /* Create workqueue */ | 923 | /* Create workqueue */ |
932 | adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); | 924 | adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); |
@@ -1038,12 +1030,12 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) | |||
1038 | dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n"); | 1030 | dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n"); |
1039 | if (atomic_read(&adapter->rx_pending) || | 1031 | if (atomic_read(&adapter->rx_pending) || |
1040 | atomic_read(&adapter->tx_pending) || | 1032 | atomic_read(&adapter->tx_pending) || |
1041 | atomic_read(&adapter->ioctl_pending)) { | 1033 | atomic_read(&adapter->cmd_pending)) { |
1042 | dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, " | 1034 | dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, " |
1043 | "ioctl_pending=%d\n", | 1035 | "cmd_pending=%d\n", |
1044 | atomic_read(&adapter->rx_pending), | 1036 | atomic_read(&adapter->rx_pending), |
1045 | atomic_read(&adapter->tx_pending), | 1037 | atomic_read(&adapter->tx_pending), |
1046 | atomic_read(&adapter->ioctl_pending)); | 1038 | atomic_read(&adapter->cmd_pending)); |
1047 | } | 1039 | } |
1048 | 1040 | ||
1049 | /* Remove interface */ | 1041 | /* Remove interface */ |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 43ff149de9db..2d296dcc210e 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -42,11 +42,8 @@ extern const char driver_version[]; | |||
42 | extern struct mwifiex_adapter *g_adapter; | 42 | extern struct mwifiex_adapter *g_adapter; |
43 | 43 | ||
44 | enum { | 44 | enum { |
45 | MWIFIEX_NO_WAIT, | 45 | MWIFIEX_ASYNC_CMD, |
46 | MWIFIEX_IOCTL_WAIT, | 46 | MWIFIEX_SYNC_CMD |
47 | MWIFIEX_CMD_WAIT, | ||
48 | MWIFIEX_PROC_WAIT, | ||
49 | MWIFIEX_WSTATS_WAIT | ||
50 | }; | 47 | }; |
51 | 48 | ||
52 | #define DRV_MODE_STA 0x1 | 49 | #define DRV_MODE_STA 0x1 |
@@ -468,10 +465,6 @@ struct mwifiex_private { | |||
468 | u32 curr_bcn_size; | 465 | u32 curr_bcn_size; |
469 | /* spin lock for beacon buffer */ | 466 | /* spin lock for beacon buffer */ |
470 | spinlock_t curr_bcn_buf_lock; | 467 | spinlock_t curr_bcn_buf_lock; |
471 | u16 ioctl_wait_q_woken; | ||
472 | wait_queue_head_t ioctl_wait_q; | ||
473 | u16 cmd_wait_q_woken; | ||
474 | wait_queue_head_t cmd_wait_q; | ||
475 | struct wireless_dev *wdev; | 468 | struct wireless_dev *wdev; |
476 | struct mwifiex_chan_freq_power cfp; | 469 | struct mwifiex_chan_freq_power cfp; |
477 | char version_str[128]; | 470 | char version_str[128]; |
@@ -480,8 +473,6 @@ struct mwifiex_private { | |||
480 | #endif | 473 | #endif |
481 | u8 nick_name[16]; | 474 | u8 nick_name[16]; |
482 | struct iw_statistics w_stats; | 475 | struct iw_statistics w_stats; |
483 | u16 w_stats_wait_q_woken; | ||
484 | wait_queue_head_t w_stats_wait_q; | ||
485 | u16 current_key_index; | 476 | u16 current_key_index; |
486 | struct semaphore async_sem; | 477 | struct semaphore async_sem; |
487 | u8 scan_pending_on_block; | 478 | u8 scan_pending_on_block; |
@@ -552,7 +543,7 @@ struct cmd_ctrl_node { | |||
552 | struct sk_buff *cmd_skb; | 543 | struct sk_buff *cmd_skb; |
553 | struct sk_buff *resp_skb; | 544 | struct sk_buff *resp_skb; |
554 | void *data_buf; | 545 | void *data_buf; |
555 | void *wq_buf; | 546 | u32 wait_q_enabled; |
556 | struct sk_buff *skb; | 547 | struct sk_buff *skb; |
557 | }; | 548 | }; |
558 | 549 | ||
@@ -590,7 +581,7 @@ struct mwifiex_adapter { | |||
590 | struct mwifiex_if_ops if_ops; | 581 | struct mwifiex_if_ops if_ops; |
591 | atomic_t rx_pending; | 582 | atomic_t rx_pending; |
592 | atomic_t tx_pending; | 583 | atomic_t tx_pending; |
593 | atomic_t ioctl_pending; | 584 | atomic_t cmd_pending; |
594 | struct workqueue_struct *workqueue; | 585 | struct workqueue_struct *workqueue; |
595 | struct work_struct main_work; | 586 | struct work_struct main_work; |
596 | struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; | 587 | struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; |
@@ -684,6 +675,8 @@ struct mwifiex_adapter { | |||
684 | struct mwifiex_dbg dbg; | 675 | struct mwifiex_dbg dbg; |
685 | u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; | 676 | u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; |
686 | u32 arp_filter_size; | 677 | u32 arp_filter_size; |
678 | u16 cmd_wait_q_required; | ||
679 | struct mwifiex_wait_queue cmd_wait_q; | ||
687 | }; | 680 | }; |
688 | 681 | ||
689 | int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); | 682 | int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); |
@@ -707,29 +700,23 @@ int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb); | |||
707 | 700 | ||
708 | int mwifiex_process_event(struct mwifiex_adapter *adapter); | 701 | int mwifiex_process_event(struct mwifiex_adapter *adapter); |
709 | 702 | ||
710 | int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, | 703 | int mwifiex_complete_cmd(struct mwifiex_adapter *adapter); |
711 | struct mwifiex_wait_queue *ioctl_wq, | ||
712 | int status); | ||
713 | 704 | ||
714 | int mwifiex_prepare_cmd(struct mwifiex_private *priv, | 705 | int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, |
715 | uint16_t cmd_no, | 706 | u16 cmd_action, u32 cmd_oid, void *data_buf); |
716 | u16 cmd_action, | 707 | |
717 | u32 cmd_oid, | 708 | int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, |
718 | void *wait_queue, void *data_buf); | 709 | u16 cmd_action, u32 cmd_oid, void *data_buf); |
719 | 710 | ||
720 | void mwifiex_cmd_timeout_func(unsigned long function_context); | 711 | void mwifiex_cmd_timeout_func(unsigned long function_context); |
721 | 712 | ||
722 | int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, | ||
723 | struct mwifiex_wait_queue *wait_queue, | ||
724 | u32 func_init_shutdown); | ||
725 | int mwifiex_get_debug_info(struct mwifiex_private *, | 713 | int mwifiex_get_debug_info(struct mwifiex_private *, |
726 | struct mwifiex_debug_info *); | 714 | struct mwifiex_debug_info *); |
727 | 715 | ||
728 | int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter); | 716 | int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter); |
729 | int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter); | 717 | int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter); |
730 | void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter); | 718 | void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter); |
731 | void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, | 719 | void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter); |
732 | struct mwifiex_wait_queue *ioctl_wq); | ||
733 | 720 | ||
734 | void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, | 721 | void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, |
735 | struct cmd_ctrl_node *cmd_node); | 722 | struct cmd_ctrl_node *cmd_node); |
@@ -772,24 +759,20 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, | |||
772 | u16 cmd_action, u32 cmd_oid, | 759 | u16 cmd_action, u32 cmd_oid, |
773 | void *data_buf, void *cmd_buf); | 760 | void *data_buf, void *cmd_buf); |
774 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, | 761 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, |
775 | void *cmd_buf, void *ioctl); | 762 | void *cmd_buf); |
776 | int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, | 763 | int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, |
777 | struct sk_buff *skb); | 764 | struct sk_buff *skb); |
778 | int mwifiex_process_sta_event(struct mwifiex_private *); | 765 | int mwifiex_process_sta_event(struct mwifiex_private *); |
779 | void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); | 766 | void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); |
780 | int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); | 767 | int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); |
781 | int mwifiex_scan_networks(struct mwifiex_private *priv, void *wait_queue, | 768 | int mwifiex_scan_networks(struct mwifiex_private *priv, |
782 | u16 action, | 769 | const struct mwifiex_user_scan_cfg *user_scan_in); |
783 | const struct mwifiex_user_scan_cfg | 770 | int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, |
784 | *user_scan_in, struct mwifiex_scan_resp *); | ||
785 | int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, | ||
786 | struct host_cmd_ds_command *cmd, | ||
787 | void *data_buf); | 771 | void *data_buf); |
788 | void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | 772 | void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, |
789 | struct cmd_ctrl_node *cmd_node); | 773 | struct cmd_ctrl_node *cmd_node); |
790 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | 774 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, |
791 | struct host_cmd_ds_command *resp, | 775 | struct host_cmd_ds_command *resp); |
792 | void *wait_queue); | ||
793 | s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv, | 776 | s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv, |
794 | struct mwifiex_802_11_ssid *ssid, u8 *bssid, | 777 | struct mwifiex_802_11_ssid *ssid, u8 *bssid, |
795 | u32 mode); | 778 | u32 mode); |
@@ -799,23 +782,20 @@ int mwifiex_find_best_network(struct mwifiex_private *priv, | |||
799 | struct mwifiex_ssid_bssid *req_ssid_bssid); | 782 | struct mwifiex_ssid_bssid *req_ssid_bssid); |
800 | s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | 783 | s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, |
801 | struct mwifiex_802_11_ssid *ssid2); | 784 | struct mwifiex_802_11_ssid *ssid2); |
802 | int mwifiex_associate(struct mwifiex_private *priv, void *wait_queue, | 785 | int mwifiex_associate(struct mwifiex_private *priv, |
803 | struct mwifiex_bssdescriptor *bss_desc); | 786 | struct mwifiex_bssdescriptor *bss_desc); |
804 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | 787 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, |
805 | struct host_cmd_ds_command | 788 | struct host_cmd_ds_command |
806 | *cmd, void *data_buf); | 789 | *cmd, void *data_buf); |
807 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | 790 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, |
808 | struct host_cmd_ds_command *resp, | 791 | struct host_cmd_ds_command *resp); |
809 | void *wait_queue); | ||
810 | void mwifiex_reset_connect_state(struct mwifiex_private *priv); | 792 | void mwifiex_reset_connect_state(struct mwifiex_private *priv); |
811 | void mwifiex_2040_coex_event(struct mwifiex_private *priv); | 793 | void mwifiex_2040_coex_event(struct mwifiex_private *priv); |
812 | u8 mwifiex_band_to_radio_type(u8 band); | 794 | u8 mwifiex_band_to_radio_type(u8 band); |
813 | int mwifiex_deauthenticate(struct mwifiex_private *priv, | 795 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); |
814 | struct mwifiex_wait_queue *wait_queue, | 796 | int mwifiex_adhoc_start(struct mwifiex_private *priv, |
815 | u8 *mac); | ||
816 | int mwifiex_adhoc_start(struct mwifiex_private *priv, void *wait_queue, | ||
817 | struct mwifiex_802_11_ssid *adhoc_ssid); | 797 | struct mwifiex_802_11_ssid *adhoc_ssid); |
818 | int mwifiex_adhoc_join(struct mwifiex_private *priv, void *wait_queue, | 798 | int mwifiex_adhoc_join(struct mwifiex_private *priv, |
819 | struct mwifiex_bssdescriptor *bss_desc); | 799 | struct mwifiex_bssdescriptor *bss_desc); |
820 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 800 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
821 | struct host_cmd_ds_command *cmd, | 801 | struct host_cmd_ds_command *cmd, |
@@ -824,11 +804,8 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
824 | struct host_cmd_ds_command *cmd, | 804 | struct host_cmd_ds_command *cmd, |
825 | void *data_buf); | 805 | void *data_buf); |
826 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | 806 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, |
827 | struct host_cmd_ds_command *resp, | 807 | struct host_cmd_ds_command *resp); |
828 | void *wait_queue); | 808 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); |
829 | int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, | ||
830 | struct host_cmd_ds_command *cmd, | ||
831 | void *data_buf); | ||
832 | struct mwifiex_chan_freq_power * | 809 | struct mwifiex_chan_freq_power * |
833 | mwifiex_get_cfp_by_band_and_channel_from_cfg80211( | 810 | mwifiex_get_cfp_by_band_and_channel_from_cfg80211( |
834 | struct mwifiex_private *priv, | 811 | struct mwifiex_private *priv, |
@@ -836,20 +813,16 @@ struct mwifiex_chan_freq_power * | |||
836 | struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( | 813 | struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( |
837 | struct mwifiex_private *priv, | 814 | struct mwifiex_private *priv, |
838 | u8 band, u32 freq); | 815 | u8 band, u32 freq); |
839 | u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, | 816 | u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info); |
840 | u8 ht_info); | ||
841 | u32 mwifiex_find_freq_from_band_chan(u8, u8); | 817 | u32 mwifiex_find_freq_from_band_chan(u8, u8); |
842 | int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, | 818 | int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, |
843 | u8 **buffer); | 819 | u8 **buffer); |
844 | u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, | ||
845 | u8 ht_info); | ||
846 | u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, | 820 | u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, |
847 | u8 *rates); | 821 | u8 *rates); |
848 | u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); | 822 | u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); |
849 | u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate); | 823 | u8 mwifiex_data_rate_to_index(u32 rate); |
850 | u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); | 824 | u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); |
851 | int mwifiex_get_rate_index(struct mwifiex_adapter *adapter, | 825 | int mwifiex_get_rate_index(u16 *rateBitmap, int size); |
852 | u16 *rateBitmap, int size); | ||
853 | extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; | 826 | extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; |
854 | void mwifiex_save_curr_bcn(struct mwifiex_private *priv); | 827 | void mwifiex_save_curr_bcn(struct mwifiex_private *priv); |
855 | void mwifiex_free_curr_bcn(struct mwifiex_private *priv); | 828 | void mwifiex_free_curr_bcn(struct mwifiex_private *priv); |
@@ -943,52 +916,34 @@ mwifiex_netdev_get_priv(struct net_device *dev) | |||
943 | return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); | 916 | return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); |
944 | } | 917 | } |
945 | 918 | ||
946 | struct mwifiex_wait_queue *mwifiex_alloc_fill_wait_queue( | ||
947 | struct mwifiex_private *, | ||
948 | u8 wait_option); | ||
949 | struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter | 919 | struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter |
950 | *adapter, u8 bss_index); | 920 | *adapter, u8 bss_index); |
951 | int mwifiex_shutdown_fw(struct mwifiex_private *, u8); | 921 | int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, |
952 | 922 | u32 func_init_shutdown); | |
953 | int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *); | 923 | int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *); |
954 | int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *); | 924 | int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *); |
955 | 925 | ||
956 | void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, | 926 | void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, |
957 | int maxlen); | 927 | int maxlen); |
958 | int mwifiex_request_set_mac_address(struct mwifiex_private *priv); | 928 | int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, |
959 | void mwifiex_request_set_multicast_list(struct mwifiex_private *priv, | 929 | struct mwifiex_multicast_list *mcast_list); |
960 | struct net_device *dev); | 930 | int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, |
961 | int mwifiex_request_ioctl(struct mwifiex_private *priv, | 931 | struct net_device *dev); |
962 | struct mwifiex_wait_queue *req, | 932 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); |
963 | int, u8 wait_option); | ||
964 | int mwifiex_disconnect(struct mwifiex_private *, u8, u8 *); | ||
965 | int mwifiex_bss_start(struct mwifiex_private *priv, | 933 | int mwifiex_bss_start(struct mwifiex_private *priv, |
966 | u8 wait_option, | ||
967 | struct mwifiex_ssid_bssid *ssid_bssid); | 934 | struct mwifiex_ssid_bssid *ssid_bssid); |
968 | int mwifiex_set_hs_params(struct mwifiex_private *priv, | 935 | int mwifiex_set_hs_params(struct mwifiex_private *priv, |
969 | u16 action, u8 wait_option, | 936 | u16 action, int cmd_type, |
970 | struct mwifiex_ds_hs_cfg *hscfg); | 937 | struct mwifiex_ds_hs_cfg *hscfg); |
971 | int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option); | 938 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); |
972 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); | 939 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); |
973 | void mwifiex_process_ioctl_resp(struct mwifiex_private *priv, | ||
974 | struct mwifiex_wait_queue *req); | ||
975 | u32 mwifiex_get_mode(struct mwifiex_private *priv, u8 wait_option); | ||
976 | int mwifiex_get_signal_info(struct mwifiex_private *priv, | 940 | int mwifiex_get_signal_info(struct mwifiex_private *priv, |
977 | u8 wait_option, | ||
978 | struct mwifiex_ds_get_signal *signal); | 941 | struct mwifiex_ds_get_signal *signal); |
979 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | 942 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, |
980 | struct mwifiex_rate_cfg *rate); | 943 | struct mwifiex_rate_cfg *rate); |
981 | int mwifiex_get_channel_list(struct mwifiex_private *priv, | 944 | int mwifiex_find_best_bss(struct mwifiex_private *priv, |
982 | u8 wait_option, | ||
983 | struct mwifiex_chan_list *chanlist); | ||
984 | int mwifiex_get_scan_table(struct mwifiex_private *priv, | ||
985 | u8 wait_option, | ||
986 | struct mwifiex_scan_resp *scanresp); | ||
987 | int mwifiex_enable_wep_key(struct mwifiex_private *priv, u8 wait_option); | ||
988 | int mwifiex_find_best_bss(struct mwifiex_private *priv, u8 wait_option, | ||
989 | struct mwifiex_ssid_bssid *ssid_bssid); | 945 | struct mwifiex_ssid_bssid *ssid_bssid); |
990 | int mwifiex_request_scan(struct mwifiex_private *priv, | 946 | int mwifiex_request_scan(struct mwifiex_private *priv, |
991 | u8 wait_option, | ||
992 | struct mwifiex_802_11_ssid *req_ssid); | 947 | struct mwifiex_802_11_ssid *req_ssid); |
993 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, | 948 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, |
994 | struct mwifiex_user_scan_cfg *scan_req); | 949 | struct mwifiex_user_scan_cfg *scan_req); |
@@ -1024,27 +979,22 @@ int mwifiex_set_tx_rate_cfg(struct mwifiex_private *priv, int tx_rate_index); | |||
1024 | 979 | ||
1025 | int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index); | 980 | int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index); |
1026 | 981 | ||
1027 | int mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on); | 982 | int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode); |
1028 | 983 | ||
1029 | int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, | 984 | int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, |
1030 | char *version, int max_len); | 985 | char *version, int max_len); |
1031 | 986 | ||
1032 | int mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm); | 987 | int mwifiex_set_tx_power(struct mwifiex_private *priv, |
988 | struct mwifiex_power_cfg *power_cfg); | ||
1033 | 989 | ||
1034 | int mwifiex_main_process(struct mwifiex_adapter *); | 990 | int mwifiex_main_process(struct mwifiex_adapter *); |
1035 | 991 | ||
1036 | int mwifiex_bss_ioctl_channel(struct mwifiex_private *, | 992 | int mwifiex_bss_set_channel(struct mwifiex_private *, |
1037 | u16 action, | 993 | struct mwifiex_chan_freq_power *cfp); |
1038 | struct mwifiex_chan_freq_power *cfp); | ||
1039 | int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *, | 994 | int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *, |
1040 | struct mwifiex_wait_queue *, | ||
1041 | struct mwifiex_ssid_bssid *); | 995 | struct mwifiex_ssid_bssid *); |
1042 | int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *, | 996 | int mwifiex_set_radio_band_cfg(struct mwifiex_private *, |
1043 | u16 action, | 997 | struct mwifiex_ds_band_cfg *); |
1044 | struct mwifiex_ds_band_cfg *); | ||
1045 | int mwifiex_snmp_mib_ioctl(struct mwifiex_private *, | ||
1046 | struct mwifiex_wait_queue *, | ||
1047 | u32 cmd_oid, u16 action, u32 *value); | ||
1048 | int mwifiex_get_bss_info(struct mwifiex_private *, | 998 | int mwifiex_get_bss_info(struct mwifiex_private *, |
1049 | struct mwifiex_bss_info *); | 999 | struct mwifiex_bss_info *); |
1050 | 1000 | ||
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 6bb52d0e6cfa..84742715893f 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -178,9 +178,8 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | |||
178 | * with requisite parameters and calls the IOCTL handler. | 178 | * with requisite parameters and calls the IOCTL handler. |
179 | */ | 179 | */ |
180 | int mwifiex_find_best_bss(struct mwifiex_private *priv, | 180 | int mwifiex_find_best_bss(struct mwifiex_private *priv, |
181 | u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid) | 181 | struct mwifiex_ssid_bssid *ssid_bssid) |
182 | { | 182 | { |
183 | struct mwifiex_wait_queue *wait = NULL; | ||
184 | struct mwifiex_ssid_bssid tmp_ssid_bssid; | 183 | struct mwifiex_ssid_bssid tmp_ssid_bssid; |
185 | int ret = 0; | 184 | int ret = 0; |
186 | u8 *mac = NULL; | 185 | u8 *mac = NULL; |
@@ -188,14 +187,9 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, | |||
188 | if (!ssid_bssid) | 187 | if (!ssid_bssid) |
189 | return -1; | 188 | return -1; |
190 | 189 | ||
191 | /* Allocate wait request buffer */ | ||
192 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
193 | if (!wait) | ||
194 | return -ENOMEM; | ||
195 | |||
196 | memcpy(&tmp_ssid_bssid, ssid_bssid, | 190 | memcpy(&tmp_ssid_bssid, ssid_bssid, |
197 | sizeof(struct mwifiex_ssid_bssid)); | 191 | sizeof(struct mwifiex_ssid_bssid)); |
198 | ret = mwifiex_bss_ioctl_find_bss(priv, wait, &tmp_ssid_bssid); | 192 | ret = mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid); |
199 | 193 | ||
200 | if (!ret) { | 194 | if (!ret) { |
201 | memcpy(ssid_bssid, &tmp_ssid_bssid, | 195 | memcpy(ssid_bssid, &tmp_ssid_bssid, |
@@ -205,7 +199,6 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, | |||
205 | " %pM\n", ssid_bssid->ssid.ssid, mac); | 199 | " %pM\n", ssid_bssid->ssid.ssid, mac); |
206 | } | 200 | } |
207 | 201 | ||
208 | kfree(wait); | ||
209 | return ret; | 202 | return ret; |
210 | } | 203 | } |
211 | 204 | ||
@@ -221,22 +214,14 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, | |||
221 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, | 214 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, |
222 | struct mwifiex_user_scan_cfg *scan_req) | 215 | struct mwifiex_user_scan_cfg *scan_req) |
223 | { | 216 | { |
224 | struct mwifiex_wait_queue *wait = NULL; | ||
225 | int status = 0; | 217 | int status = 0; |
226 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
227 | |||
228 | /* Allocate an IOCTL request buffer */ | ||
229 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
230 | if (!wait) | ||
231 | return -ENOMEM; | ||
232 | 218 | ||
233 | status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, | 219 | priv->adapter->cmd_wait_q.condition = false; |
234 | scan_req, NULL); | ||
235 | 220 | ||
236 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | 221 | status = mwifiex_scan_networks(priv, scan_req); |
222 | if (!status) | ||
223 | status = mwifiex_wait_queue_complete(priv->adapter); | ||
237 | 224 | ||
238 | if (wait && (status != -EINPROGRESS)) | ||
239 | kfree(wait); | ||
240 | return status; | 225 | return status; |
241 | } | 226 | } |
242 | 227 | ||
@@ -674,7 +659,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | |||
674 | * along with the other TLVs, to the firmware. | 659 | * along with the other TLVs, to the firmware. |
675 | */ | 660 | */ |
676 | static int | 661 | static int |
677 | mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, | 662 | mwifiex_scan_channel_list(struct mwifiex_private *priv, |
678 | u32 max_chan_per_scan, u8 filtered_scan, | 663 | u32 max_chan_per_scan, u8 filtered_scan, |
679 | struct mwifiex_scan_cmd_config *scan_cfg_out, | 664 | struct mwifiex_scan_cmd_config *scan_cfg_out, |
680 | struct mwifiex_ie_types_chan_list_param_set | 665 | struct mwifiex_ie_types_chan_list_param_set |
@@ -808,9 +793,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, | |||
808 | 793 | ||
809 | /* Send the scan command to the firmware with the specified | 794 | /* Send the scan command to the firmware with the specified |
810 | cfg */ | 795 | cfg */ |
811 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SCAN, | 796 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN, |
812 | HostCmd_ACT_GEN_SET, | 797 | HostCmd_ACT_GEN_SET, 0, |
813 | 0, wait_buf, scan_cfg_out); | 798 | scan_cfg_out); |
814 | if (ret) | 799 | if (ret) |
815 | break; | 800 | break; |
816 | } | 801 | } |
@@ -2271,9 +2256,7 @@ mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, | |||
2271 | * update the internal driver scan table. | 2256 | * update the internal driver scan table. |
2272 | */ | 2257 | */ |
2273 | int mwifiex_scan_networks(struct mwifiex_private *priv, | 2258 | int mwifiex_scan_networks(struct mwifiex_private *priv, |
2274 | void *wait_buf, u16 action, | 2259 | const struct mwifiex_user_scan_cfg *user_scan_in) |
2275 | const struct mwifiex_user_scan_cfg *user_scan_in, | ||
2276 | struct mwifiex_scan_resp *scan_resp) | ||
2277 | { | 2260 | { |
2278 | int ret = 0; | 2261 | int ret = 0; |
2279 | struct mwifiex_adapter *adapter = priv->adapter; | 2262 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -2288,18 +2271,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2288 | u8 max_chan_per_scan; | 2271 | u8 max_chan_per_scan; |
2289 | unsigned long flags; | 2272 | unsigned long flags; |
2290 | 2273 | ||
2291 | if (action == HostCmd_ACT_GEN_GET) { | 2274 | if (adapter->scan_processing) { |
2292 | if (scan_resp) { | ||
2293 | scan_resp->scan_table = (u8 *) adapter->scan_table; | ||
2294 | scan_resp->num_in_scan_table = | ||
2295 | adapter->num_in_scan_table; | ||
2296 | } else { | ||
2297 | ret = -1; | ||
2298 | } | ||
2299 | return ret; | ||
2300 | } | ||
2301 | |||
2302 | if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { | ||
2303 | dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); | 2275 | dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); |
2304 | return ret; | 2276 | return ret; |
2305 | } | 2277 | } |
@@ -2308,7 +2280,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2308 | adapter->scan_processing = true; | 2280 | adapter->scan_processing = true; |
2309 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | 2281 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
2310 | 2282 | ||
2311 | if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { | 2283 | if (priv->scan_block) { |
2312 | dev_dbg(adapter->dev, | 2284 | dev_dbg(adapter->dev, |
2313 | "cmd: Scan is blocked during association...\n"); | 2285 | "cmd: Scan is blocked during association...\n"); |
2314 | return ret; | 2286 | return ret; |
@@ -2348,9 +2320,9 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2348 | adapter->bcn_buf_end = adapter->bcn_buf; | 2320 | adapter->bcn_buf_end = adapter->bcn_buf; |
2349 | } | 2321 | } |
2350 | 2322 | ||
2351 | ret = mwifiex_scan_channel_list(priv, wait_buf, max_chan_per_scan, | 2323 | ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, |
2352 | filtered_scan, &scan_cfg_out->config, | 2324 | &scan_cfg_out->config, chan_list_out, |
2353 | chan_list_out, scan_chan_list); | 2325 | scan_chan_list); |
2354 | 2326 | ||
2355 | /* Get scan command from scan_pending_q and put to cmd_pending_q */ | 2327 | /* Get scan command from scan_pending_q and put to cmd_pending_q */ |
2356 | if (!ret) { | 2328 | if (!ret) { |
@@ -2367,7 +2339,6 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2367 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 2339 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
2368 | flags); | 2340 | flags); |
2369 | } | 2341 | } |
2370 | ret = -EINPROGRESS; | ||
2371 | } else { | 2342 | } else { |
2372 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 2343 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
2373 | adapter->scan_processing = true; | 2344 | adapter->scan_processing = true; |
@@ -2393,8 +2364,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2393 | * - Setting command ID, and proper size | 2364 | * - Setting command ID, and proper size |
2394 | * - Ensuring correct endian-ness | 2365 | * - Ensuring correct endian-ness |
2395 | */ | 2366 | */ |
2396 | int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, | 2367 | int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf) |
2397 | struct host_cmd_ds_command *cmd, void *data_buf) | ||
2398 | { | 2368 | { |
2399 | struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; | 2369 | struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; |
2400 | struct mwifiex_scan_cmd_config *scan_cfg; | 2370 | struct mwifiex_scan_cmd_config *scan_cfg; |
@@ -2437,11 +2407,10 @@ int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, | |||
2437 | * .-------------------------------------------------------------. | 2407 | * .-------------------------------------------------------------. |
2438 | */ | 2408 | */ |
2439 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | 2409 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, |
2440 | struct host_cmd_ds_command *resp, void *wq_buf) | 2410 | struct host_cmd_ds_command *resp) |
2441 | { | 2411 | { |
2442 | int ret = 0; | 2412 | int ret = 0; |
2443 | struct mwifiex_adapter *adapter = priv->adapter; | 2413 | struct mwifiex_adapter *adapter = priv->adapter; |
2444 | struct mwifiex_wait_queue *wait_queue = NULL; | ||
2445 | struct cmd_ctrl_node *cmd_node = NULL; | 2414 | struct cmd_ctrl_node *cmd_node = NULL; |
2446 | struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL; | 2415 | struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL; |
2447 | struct mwifiex_bssdescriptor *bss_new_entry = NULL; | 2416 | struct mwifiex_bssdescriptor *bss_new_entry = NULL; |
@@ -2653,13 +2622,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
2653 | mwifiex_process_scan_results(priv); | 2622 | mwifiex_process_scan_results(priv); |
2654 | 2623 | ||
2655 | /* Need to indicate IOCTL complete */ | 2624 | /* Need to indicate IOCTL complete */ |
2656 | wait_queue = (struct mwifiex_wait_queue *) wq_buf; | 2625 | if (adapter->curr_cmd->wait_q_enabled) { |
2657 | if (wait_queue) { | 2626 | adapter->cmd_wait_q.status = 0; |
2658 | wait_queue->status = MWIFIEX_ERROR_NO_ERROR; | 2627 | mwifiex_complete_cmd(adapter); |
2659 | |||
2660 | /* Indicate ioctl complete */ | ||
2661 | mwifiex_ioctl_complete(adapter, | ||
2662 | (struct mwifiex_wait_queue *) wait_queue, 0); | ||
2663 | } | 2628 | } |
2664 | if (priv->report_scan_result) | 2629 | if (priv->report_scan_result) |
2665 | priv->report_scan_result = false; | 2630 | priv->report_scan_result = false; |
@@ -2692,9 +2657,7 @@ done: | |||
2692 | * - Setting background scan flush parameter | 2657 | * - Setting background scan flush parameter |
2693 | * - Ensuring correct endian-ness | 2658 | * - Ensuring correct endian-ness |
2694 | */ | 2659 | */ |
2695 | int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, | 2660 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd) |
2696 | struct host_cmd_ds_command *cmd, | ||
2697 | void *data_buf) | ||
2698 | { | 2661 | { |
2699 | struct host_cmd_ds_802_11_bg_scan_query *bg_query = | 2662 | struct host_cmd_ds_802_11_bg_scan_query *bg_query = |
2700 | &cmd->params.bg_scan_query; | 2663 | &cmd->params.bg_scan_query; |
@@ -2853,6 +2816,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | |||
2853 | struct mwifiex_adapter *adapter = priv->adapter; | 2816 | struct mwifiex_adapter *adapter = priv->adapter; |
2854 | unsigned long flags; | 2817 | unsigned long flags; |
2855 | 2818 | ||
2819 | cmd_node->wait_q_enabled = true; | ||
2856 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 2820 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
2857 | list_add_tail(&cmd_node->list, &adapter->scan_pending_q); | 2821 | list_add_tail(&cmd_node->list, &adapter->scan_pending_q); |
2858 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | 2822 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); |
@@ -2899,9 +2863,7 @@ int mwifiex_find_best_network(struct mwifiex_private *priv, | |||
2899 | * firmware, filtered on a specific SSID. | 2863 | * firmware, filtered on a specific SSID. |
2900 | */ | 2864 | */ |
2901 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | 2865 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, |
2902 | void *wait_buf, u16 action, | 2866 | struct mwifiex_802_11_ssid *req_ssid) |
2903 | struct mwifiex_802_11_ssid *req_ssid, | ||
2904 | struct mwifiex_scan_resp *scan_resp) | ||
2905 | { | 2867 | { |
2906 | struct mwifiex_adapter *adapter = priv->adapter; | 2868 | struct mwifiex_adapter *adapter = priv->adapter; |
2907 | int ret = 0; | 2869 | int ret = 0; |
@@ -2910,24 +2872,12 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
2910 | if (!req_ssid) | 2872 | if (!req_ssid) |
2911 | return -1; | 2873 | return -1; |
2912 | 2874 | ||
2913 | if (action == HostCmd_ACT_GEN_GET) { | 2875 | if (adapter->scan_processing) { |
2914 | if (scan_resp) { | ||
2915 | scan_resp->scan_table = | ||
2916 | (u8 *) &priv->curr_bss_params.bss_descriptor; | ||
2917 | scan_resp->num_in_scan_table = | ||
2918 | adapter->num_in_scan_table; | ||
2919 | } else { | ||
2920 | ret = -1; | ||
2921 | } | ||
2922 | return ret; | ||
2923 | } | ||
2924 | |||
2925 | if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { | ||
2926 | dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); | 2876 | dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); |
2927 | return ret; | 2877 | return ret; |
2928 | } | 2878 | } |
2929 | 2879 | ||
2930 | if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { | 2880 | if (priv->scan_block) { |
2931 | dev_dbg(adapter->dev, | 2881 | dev_dbg(adapter->dev, |
2932 | "cmd: Scan is blocked during association...\n"); | 2882 | "cmd: Scan is blocked during association...\n"); |
2933 | return ret; | 2883 | return ret; |
@@ -2945,7 +2895,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
2945 | req_ssid->ssid_len); | 2895 | req_ssid->ssid_len); |
2946 | scan_cfg->keep_previous_scan = true; | 2896 | scan_cfg->keep_previous_scan = true; |
2947 | 2897 | ||
2948 | ret = mwifiex_scan_networks(priv, wait_buf, action, scan_cfg, NULL); | 2898 | ret = mwifiex_scan_networks(priv, scan_cfg); |
2949 | 2899 | ||
2950 | kfree(scan_cfg); | 2900 | kfree(scan_cfg); |
2951 | return ret; | 2901 | return ret; |
@@ -2960,12 +2910,10 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
2960 | * Scan command can be issued for both normal scan and specific SSID | 2910 | * Scan command can be issued for both normal scan and specific SSID |
2961 | * scan, depending upon whether an SSID is provided or not. | 2911 | * scan, depending upon whether an SSID is provided or not. |
2962 | */ | 2912 | */ |
2963 | int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, | 2913 | int mwifiex_request_scan(struct mwifiex_private *priv, |
2964 | struct mwifiex_802_11_ssid *req_ssid) | 2914 | struct mwifiex_802_11_ssid *req_ssid) |
2965 | { | 2915 | { |
2966 | int ret = 0; | 2916 | int ret = 0; |
2967 | struct mwifiex_wait_queue *wait = NULL; | ||
2968 | int status = 0; | ||
2969 | 2917 | ||
2970 | if (down_interruptible(&priv->async_sem)) { | 2918 | if (down_interruptible(&priv->async_sem)) { |
2971 | dev_err(priv->adapter->dev, "%s: acquire semaphore\n", | 2919 | dev_err(priv->adapter->dev, "%s: acquire semaphore\n", |
@@ -2974,32 +2922,23 @@ int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, | |||
2974 | } | 2922 | } |
2975 | priv->scan_pending_on_block = true; | 2923 | priv->scan_pending_on_block = true; |
2976 | 2924 | ||
2977 | /* Allocate wait request buffer */ | 2925 | priv->adapter->cmd_wait_q.condition = false; |
2978 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
2979 | if (!wait) { | ||
2980 | ret = -1; | ||
2981 | goto done; | ||
2982 | } | ||
2983 | 2926 | ||
2984 | if (req_ssid && req_ssid->ssid_len != 0) | 2927 | if (req_ssid && req_ssid->ssid_len != 0) |
2985 | /* Specific SSID scan */ | 2928 | /* Specific SSID scan */ |
2986 | status = mwifiex_scan_specific_ssid(priv, wait, | 2929 | ret = mwifiex_scan_specific_ssid(priv, req_ssid); |
2987 | HostCmd_ACT_GEN_SET, | ||
2988 | req_ssid, NULL); | ||
2989 | else | 2930 | else |
2990 | /* Normal scan */ | 2931 | /* Normal scan */ |
2991 | status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, | 2932 | ret = mwifiex_scan_networks(priv, NULL); |
2992 | NULL, NULL); | 2933 | |
2993 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | 2934 | if (!ret) |
2994 | if (status == -1) | 2935 | ret = mwifiex_wait_queue_complete(priv->adapter); |
2995 | ret = -1; | 2936 | |
2996 | done: | ||
2997 | if ((wait) && (status != -EINPROGRESS)) | ||
2998 | kfree(wait); | ||
2999 | if (ret == -1) { | 2937 | if (ret == -1) { |
3000 | priv->scan_pending_on_block = false; | 2938 | priv->scan_pending_on_block = false; |
3001 | up(&priv->async_sem); | 2939 | up(&priv->async_sem); |
3002 | } | 2940 | } |
2941 | |||
3003 | return ret; | 2942 | return ret; |
3004 | } | 2943 | } |
3005 | 2944 | ||
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index f21e5cd19839..41c087d3f0f5 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -208,7 +208,7 @@ static int mwifiex_sdio_resume(struct device *dev) | |||
208 | 208 | ||
209 | /* Disable Host Sleep */ | 209 | /* Disable Host Sleep */ |
210 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), | 210 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), |
211 | MWIFIEX_NO_WAIT); | 211 | MWIFIEX_ASYNC_CMD); |
212 | 212 | ||
213 | return 0; | 213 | return 0; |
214 | } | 214 | } |
@@ -282,7 +282,7 @@ mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data) | |||
282 | */ | 282 | */ |
283 | static int | 283 | static int |
284 | mwifiex_write_data_sync(struct mwifiex_adapter *adapter, | 284 | mwifiex_write_data_sync(struct mwifiex_adapter *adapter, |
285 | u8 *buffer, u32 pkt_len, u32 port, u32 timeout) | 285 | u8 *buffer, u32 pkt_len, u32 port) |
286 | { | 286 | { |
287 | struct sdio_mmc_card *card = adapter->card; | 287 | struct sdio_mmc_card *card = adapter->card; |
288 | int ret = -1; | 288 | int ret = -1; |
@@ -314,9 +314,8 @@ mwifiex_write_data_sync(struct mwifiex_adapter *adapter, | |||
314 | /* | 314 | /* |
315 | * This function reads multiple data from SDIO card memory. | 315 | * This function reads multiple data from SDIO card memory. |
316 | */ | 316 | */ |
317 | static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, | 317 | static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, |
318 | u8 *buffer, u32 len, | 318 | u32 len, u32 port, u8 claim) |
319 | u32 port, u32 timeout, u8 claim) | ||
320 | { | 319 | { |
321 | struct sdio_mmc_card *card = adapter->card; | 320 | struct sdio_mmc_card *card = adapter->card; |
322 | int ret = -1; | 321 | int ret = -1; |
@@ -430,8 +429,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, | |||
430 | int ret = 0; | 429 | int ret = 0; |
431 | 430 | ||
432 | do { | 431 | do { |
433 | ret = mwifiex_write_data_sync(adapter, payload, pkt_len, | 432 | ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port); |
434 | port, 0); | ||
435 | if (ret) { | 433 | if (ret) { |
436 | i++; | 434 | i++; |
437 | dev_err(adapter->dev, "host_to_card, write iomem" | 435 | dev_err(adapter->dev, "host_to_card, write iomem" |
@@ -630,7 +628,7 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, | |||
630 | return -1; | 628 | return -1; |
631 | } | 629 | } |
632 | 630 | ||
633 | ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 0, 1); | 631 | ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 1); |
634 | 632 | ||
635 | if (ret) { | 633 | if (ret) { |
636 | dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, | 634 | dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, |
@@ -769,7 +767,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
769 | 767 | ||
770 | ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks * | 768 | ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks * |
771 | MWIFIEX_SDIO_BLOCK_SIZE, | 769 | MWIFIEX_SDIO_BLOCK_SIZE, |
772 | adapter->ioport, 0); | 770 | adapter->ioport); |
773 | if (ret) { | 771 | if (ret) { |
774 | dev_err(adapter->dev, "FW download, write iomem (%d)" | 772 | dev_err(adapter->dev, "FW download, write iomem (%d)" |
775 | " failed @ %d\n", i, offset); | 773 | " failed @ %d\n", i, offset); |
@@ -842,7 +840,7 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
842 | unsigned long flags; | 840 | unsigned long flags; |
843 | 841 | ||
844 | if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, | 842 | if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, |
845 | REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0, | 843 | REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, |
846 | 0)) { | 844 | 0)) { |
847 | dev_err(adapter->dev, "read mp_regs failed\n"); | 845 | dev_err(adapter->dev, "read mp_regs failed\n"); |
848 | return; | 846 | return; |
@@ -859,8 +857,6 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
859 | adapter->int_status |= sdio_ireg; | 857 | adapter->int_status |= sdio_ireg; |
860 | spin_unlock_irqrestore(&adapter->int_lock, flags); | 858 | spin_unlock_irqrestore(&adapter->int_lock, flags); |
861 | } | 859 | } |
862 | |||
863 | return; | ||
864 | } | 860 | } |
865 | 861 | ||
866 | /* | 862 | /* |
@@ -891,8 +887,6 @@ mwifiex_sdio_interrupt(struct sdio_func *func) | |||
891 | 887 | ||
892 | mwifiex_interrupt_status(adapter); | 888 | mwifiex_interrupt_status(adapter); |
893 | queue_work(adapter->workqueue, &adapter->main_work); | 889 | queue_work(adapter->workqueue, &adapter->main_work); |
894 | |||
895 | return; | ||
896 | } | 890 | } |
897 | 891 | ||
898 | /* | 892 | /* |
@@ -1054,7 +1048,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1054 | card->mpa_rx.buf_len, | 1048 | card->mpa_rx.buf_len, |
1055 | (adapter->ioport | 0x1000 | | 1049 | (adapter->ioport | 0x1000 | |
1056 | (card->mpa_rx.ports << 4)) + | 1050 | (card->mpa_rx.ports << 4)) + |
1057 | card->mpa_rx.start_port, 0, 1)) | 1051 | card->mpa_rx.start_port, 1)) |
1058 | return -1; | 1052 | return -1; |
1059 | 1053 | ||
1060 | curr_ptr = card->mpa_rx.buf; | 1054 | curr_ptr = card->mpa_rx.buf; |
@@ -1745,13 +1739,12 @@ mwifiex_sdio_cleanup_module(void) | |||
1745 | for (i = 0; i < adapter->priv_num; i++) | 1739 | for (i = 0; i < adapter->priv_num; i++) |
1746 | if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && | 1740 | if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && |
1747 | adapter->priv[i]->media_connected) | 1741 | adapter->priv[i]->media_connected) |
1748 | mwifiex_disconnect(adapter->priv[i], MWIFIEX_CMD_WAIT, | 1742 | mwifiex_deauthenticate(adapter->priv[i], NULL); |
1749 | NULL); | ||
1750 | 1743 | ||
1751 | if (!adapter->surprise_removed) | 1744 | if (!adapter->surprise_removed) |
1752 | mwifiex_shutdown_fw(mwifiex_get_priv | 1745 | mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, |
1753 | (adapter, MWIFIEX_BSS_ROLE_ANY), | 1746 | MWIFIEX_BSS_ROLE_ANY), |
1754 | MWIFIEX_CMD_WAIT); | 1747 | MWIFIEX_FUNC_SHUTDOWN); |
1755 | 1748 | ||
1756 | exit: | 1749 | exit: |
1757 | up(&add_remove_card_sem); | 1750 | up(&add_remove_card_sem); |
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 6fff26153e26..33c8ba1f5e33 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -190,8 +190,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, | |||
190 | * - Ensuring correct endian-ness | 190 | * - Ensuring correct endian-ness |
191 | */ | 191 | */ |
192 | static int | 192 | static int |
193 | mwifiex_cmd_802_11_get_log(struct mwifiex_private *priv, | 193 | mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd) |
194 | struct host_cmd_ds_command *cmd) | ||
195 | { | 194 | { |
196 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG); | 195 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG); |
197 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) + | 196 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) + |
@@ -272,8 +271,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, | |||
272 | * (as required) | 271 | * (as required) |
273 | * - Ensuring correct endian-ness | 272 | * - Ensuring correct endian-ness |
274 | */ | 273 | */ |
275 | static int mwifiex_cmd_tx_power_cfg(struct mwifiex_private *priv, | 274 | static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, |
276 | struct host_cmd_ds_command *cmd, | ||
277 | u16 cmd_action, void *data_buf) | 275 | u16 cmd_action, void *data_buf) |
278 | { | 276 | { |
279 | struct mwifiex_types_power_group *pg_tlv = NULL; | 277 | struct mwifiex_types_power_group *pg_tlv = NULL; |
@@ -407,8 +405,7 @@ static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv, | |||
407 | * - Setting MAC multicast address | 405 | * - Setting MAC multicast address |
408 | * - Ensuring correct endian-ness | 406 | * - Ensuring correct endian-ness |
409 | */ | 407 | */ |
410 | static int mwifiex_cmd_mac_multicast_adr(struct mwifiex_private *priv, | 408 | static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, |
411 | struct host_cmd_ds_command *cmd, | ||
412 | u16 cmd_action, void *data_buf) | 409 | u16 cmd_action, void *data_buf) |
413 | { | 410 | { |
414 | struct mwifiex_multicast_list *mcast_list = | 411 | struct mwifiex_multicast_list *mcast_list = |
@@ -463,8 +460,7 @@ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, | |||
463 | * - Setting command ID and proper size | 460 | * - Setting command ID and proper size |
464 | * - Ensuring correct endian-ness | 461 | * - Ensuring correct endian-ness |
465 | */ | 462 | */ |
466 | static int mwifiex_cmd_802_11_ad_hoc_stop(struct mwifiex_private *priv, | 463 | static int mwifiex_cmd_802_11_ad_hoc_stop(struct host_cmd_ds_command *cmd) |
467 | struct host_cmd_ds_command *cmd) | ||
468 | { | 464 | { |
469 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP); | 465 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP); |
470 | cmd->size = cpu_to_le16(S_DS_GEN); | 466 | cmd->size = cpu_to_le16(S_DS_GEN); |
@@ -500,9 +496,8 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, | |||
500 | key_param_set->key_type_id = | 496 | key_param_set->key_type_id = |
501 | cpu_to_le16(KEY_TYPE_ID_WEP); | 497 | cpu_to_le16(KEY_TYPE_ID_WEP); |
502 | key_param_set->key_info = | 498 | key_param_set->key_info = |
503 | cpu_to_le16(KEY_INFO_WEP_ENABLED | | 499 | cpu_to_le16(KEY_ENABLED | KEY_UNICAST | |
504 | KEY_INFO_WEP_UNICAST | | 500 | KEY_MCAST); |
505 | KEY_INFO_WEP_MCAST); | ||
506 | key_param_set->key_len = | 501 | key_param_set->key_len = |
507 | cpu_to_le16(priv->wep_key[i].key_length); | 502 | cpu_to_le16(priv->wep_key[i].key_length); |
508 | /* Set WEP key index */ | 503 | /* Set WEP key index */ |
@@ -589,10 +584,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
589 | cpu_to_le16(KEY_TYPE_ID_WAPI); | 584 | cpu_to_le16(KEY_TYPE_ID_WAPI); |
590 | if (cmd_oid == KEY_INFO_ENABLED) | 585 | if (cmd_oid == KEY_INFO_ENABLED) |
591 | key_material->key_param_set.key_info = | 586 | key_material->key_param_set.key_info = |
592 | cpu_to_le16(KEY_INFO_WAPI_ENABLED); | 587 | cpu_to_le16(KEY_ENABLED); |
593 | else | 588 | else |
594 | key_material->key_param_set.key_info = | 589 | key_material->key_param_set.key_info = |
595 | cpu_to_le16(!KEY_INFO_WAPI_ENABLED); | 590 | cpu_to_le16(!KEY_ENABLED); |
596 | 591 | ||
597 | key_material->key_param_set.key[0] = enc_key->key_index; | 592 | key_material->key_param_set.key[0] = enc_key->key_index; |
598 | if (!priv->sec_info.wapi_key_on) | 593 | if (!priv->sec_info.wapi_key_on) |
@@ -604,10 +599,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
604 | if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) { | 599 | if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) { |
605 | /* WAPI pairwise key: unicast */ | 600 | /* WAPI pairwise key: unicast */ |
606 | key_material->key_param_set.key_info |= | 601 | key_material->key_param_set.key_info |= |
607 | cpu_to_le16(KEY_INFO_WAPI_UNICAST); | 602 | cpu_to_le16(KEY_UNICAST); |
608 | } else { /* WAPI group key: multicast */ | 603 | } else { /* WAPI group key: multicast */ |
609 | key_material->key_param_set.key_info |= | 604 | key_material->key_param_set.key_info |= |
610 | cpu_to_le16(KEY_INFO_WAPI_MCAST); | 605 | cpu_to_le16(KEY_MCAST); |
611 | priv->sec_info.wapi_key_on = true; | 606 | priv->sec_info.wapi_key_on = true; |
612 | } | 607 | } |
613 | 608 | ||
@@ -634,32 +629,32 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
634 | cpu_to_le16(KEY_TYPE_ID_AES); | 629 | cpu_to_le16(KEY_TYPE_ID_AES); |
635 | if (cmd_oid == KEY_INFO_ENABLED) | 630 | if (cmd_oid == KEY_INFO_ENABLED) |
636 | key_material->key_param_set.key_info = | 631 | key_material->key_param_set.key_info = |
637 | cpu_to_le16(KEY_INFO_AES_ENABLED); | 632 | cpu_to_le16(KEY_ENABLED); |
638 | else | 633 | else |
639 | key_material->key_param_set.key_info = | 634 | key_material->key_param_set.key_info = |
640 | cpu_to_le16(!KEY_INFO_AES_ENABLED); | 635 | cpu_to_le16(!KEY_ENABLED); |
641 | 636 | ||
642 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) | 637 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) |
643 | /* AES pairwise key: unicast */ | 638 | /* AES pairwise key: unicast */ |
644 | key_material->key_param_set.key_info |= | 639 | key_material->key_param_set.key_info |= |
645 | cpu_to_le16(KEY_INFO_AES_UNICAST); | 640 | cpu_to_le16(KEY_UNICAST); |
646 | else /* AES group key: multicast */ | 641 | else /* AES group key: multicast */ |
647 | key_material->key_param_set.key_info |= | 642 | key_material->key_param_set.key_info |= |
648 | cpu_to_le16(KEY_INFO_AES_MCAST); | 643 | cpu_to_le16(KEY_MCAST); |
649 | } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { | 644 | } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { |
650 | dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); | 645 | dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); |
651 | key_material->key_param_set.key_type_id = | 646 | key_material->key_param_set.key_type_id = |
652 | cpu_to_le16(KEY_TYPE_ID_TKIP); | 647 | cpu_to_le16(KEY_TYPE_ID_TKIP); |
653 | key_material->key_param_set.key_info = | 648 | key_material->key_param_set.key_info = |
654 | cpu_to_le16(KEY_INFO_TKIP_ENABLED); | 649 | cpu_to_le16(KEY_ENABLED); |
655 | 650 | ||
656 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) | 651 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) |
657 | /* TKIP pairwise key: unicast */ | 652 | /* TKIP pairwise key: unicast */ |
658 | key_material->key_param_set.key_info |= | 653 | key_material->key_param_set.key_info |= |
659 | cpu_to_le16(KEY_INFO_TKIP_UNICAST); | 654 | cpu_to_le16(KEY_UNICAST); |
660 | else /* TKIP group key: multicast */ | 655 | else /* TKIP group key: multicast */ |
661 | key_material->key_param_set.key_info |= | 656 | key_material->key_param_set.key_info |= |
662 | cpu_to_le16(KEY_INFO_TKIP_MCAST); | 657 | cpu_to_le16(KEY_MCAST); |
663 | } | 658 | } |
664 | 659 | ||
665 | if (key_material->key_param_set.key_type_id) { | 660 | if (key_material->key_param_set.key_type_id) { |
@@ -778,8 +773,7 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, | |||
778 | * - Setting status to enable or disable (for SET only) | 773 | * - Setting status to enable or disable (for SET only) |
779 | * - Ensuring correct endian-ness | 774 | * - Ensuring correct endian-ness |
780 | */ | 775 | */ |
781 | static int mwifiex_cmd_ibss_coalescing_status(struct mwifiex_private *priv, | 776 | static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, |
782 | struct host_cmd_ds_command *cmd, | ||
783 | u16 cmd_action, void *data_buf) | 777 | u16 cmd_action, void *data_buf) |
784 | { | 778 | { |
785 | struct host_cmd_ds_802_11_ibss_status *ibss_coal = | 779 | struct host_cmd_ds_802_11_ibss_status *ibss_coal = |
@@ -947,7 +941,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
947 | cmd_action); | 941 | cmd_action); |
948 | break; | 942 | break; |
949 | case HostCmd_CMD_MAC_MULTICAST_ADR: | 943 | case HostCmd_CMD_MAC_MULTICAST_ADR: |
950 | ret = mwifiex_cmd_mac_multicast_adr(priv, cmd_ptr, cmd_action, | 944 | ret = mwifiex_cmd_mac_multicast_adr(cmd_ptr, cmd_action, |
951 | data_buf); | 945 | data_buf); |
952 | break; | 946 | break; |
953 | case HostCmd_CMD_TX_RATE_CFG: | 947 | case HostCmd_CMD_TX_RATE_CFG: |
@@ -955,7 +949,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
955 | data_buf); | 949 | data_buf); |
956 | break; | 950 | break; |
957 | case HostCmd_CMD_TXPWR_CFG: | 951 | case HostCmd_CMD_TXPWR_CFG: |
958 | ret = mwifiex_cmd_tx_power_cfg(priv, cmd_ptr, cmd_action, | 952 | ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action, |
959 | data_buf); | 953 | data_buf); |
960 | break; | 954 | break; |
961 | case HostCmd_CMD_802_11_PS_MODE_ENH: | 955 | case HostCmd_CMD_802_11_PS_MODE_ENH: |
@@ -967,11 +961,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
967 | (struct mwifiex_hs_config_param *) data_buf); | 961 | (struct mwifiex_hs_config_param *) data_buf); |
968 | break; | 962 | break; |
969 | case HostCmd_CMD_802_11_SCAN: | 963 | case HostCmd_CMD_802_11_SCAN: |
970 | ret = mwifiex_cmd_802_11_scan(priv, cmd_ptr, data_buf); | 964 | ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf); |
971 | break; | 965 | break; |
972 | case HostCmd_CMD_802_11_BG_SCAN_QUERY: | 966 | case HostCmd_CMD_802_11_BG_SCAN_QUERY: |
973 | ret = mwifiex_cmd_802_11_bg_scan_query(priv, cmd_ptr, | 967 | ret = mwifiex_cmd_802_11_bg_scan_query(cmd_ptr); |
974 | data_buf); | ||
975 | break; | 968 | break; |
976 | case HostCmd_CMD_802_11_ASSOCIATE: | 969 | case HostCmd_CMD_802_11_ASSOCIATE: |
977 | ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf); | 970 | ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf); |
@@ -985,14 +978,14 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
985 | data_buf); | 978 | data_buf); |
986 | break; | 979 | break; |
987 | case HostCmd_CMD_802_11_GET_LOG: | 980 | case HostCmd_CMD_802_11_GET_LOG: |
988 | ret = mwifiex_cmd_802_11_get_log(priv, cmd_ptr); | 981 | ret = mwifiex_cmd_802_11_get_log(cmd_ptr); |
989 | break; | 982 | break; |
990 | case HostCmd_CMD_802_11_AD_HOC_JOIN: | 983 | case HostCmd_CMD_802_11_AD_HOC_JOIN: |
991 | ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr, | 984 | ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr, |
992 | data_buf); | 985 | data_buf); |
993 | break; | 986 | break; |
994 | case HostCmd_CMD_802_11_AD_HOC_STOP: | 987 | case HostCmd_CMD_802_11_AD_HOC_STOP: |
995 | ret = mwifiex_cmd_802_11_ad_hoc_stop(priv, cmd_ptr); | 988 | ret = mwifiex_cmd_802_11_ad_hoc_stop(cmd_ptr); |
996 | break; | 989 | break; |
997 | case HostCmd_CMD_RSSI_INFO: | 990 | case HostCmd_CMD_RSSI_INFO: |
998 | ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action); | 991 | ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action); |
@@ -1037,10 +1030,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1037 | cmd_ptr->size = cpu_to_le16(S_DS_GEN); | 1030 | cmd_ptr->size = cpu_to_le16(S_DS_GEN); |
1038 | break; | 1031 | break; |
1039 | case HostCmd_CMD_11N_ADDBA_REQ: | 1032 | case HostCmd_CMD_11N_ADDBA_REQ: |
1040 | ret = mwifiex_cmd_11n_addba_req(priv, cmd_ptr, data_buf); | 1033 | ret = mwifiex_cmd_11n_addba_req(cmd_ptr, data_buf); |
1041 | break; | 1034 | break; |
1042 | case HostCmd_CMD_11N_DELBA: | 1035 | case HostCmd_CMD_11N_DELBA: |
1043 | ret = mwifiex_cmd_11n_delba(priv, cmd_ptr, data_buf); | 1036 | ret = mwifiex_cmd_11n_delba(cmd_ptr, data_buf); |
1044 | break; | 1037 | break; |
1045 | case HostCmd_CMD_11N_ADDBA_RSP: | 1038 | case HostCmd_CMD_11N_ADDBA_RSP: |
1046 | ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf); | 1039 | ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf); |
@@ -1059,11 +1052,11 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1059 | data_buf); | 1052 | data_buf); |
1060 | break; | 1053 | break; |
1061 | case HostCmd_CMD_AMSDU_AGGR_CTRL: | 1054 | case HostCmd_CMD_AMSDU_AGGR_CTRL: |
1062 | ret = mwifiex_cmd_amsdu_aggr_ctrl(priv, cmd_ptr, cmd_action, | 1055 | ret = mwifiex_cmd_amsdu_aggr_ctrl(cmd_ptr, cmd_action, |
1063 | data_buf); | 1056 | data_buf); |
1064 | break; | 1057 | break; |
1065 | case HostCmd_CMD_11N_CFG: | 1058 | case HostCmd_CMD_11N_CFG: |
1066 | ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action, | 1059 | ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, |
1067 | data_buf); | 1060 | data_buf); |
1068 | break; | 1061 | break; |
1069 | case HostCmd_CMD_WMM_GET_STATUS: | 1062 | case HostCmd_CMD_WMM_GET_STATUS: |
@@ -1076,8 +1069,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1076 | ret = 0; | 1069 | ret = 0; |
1077 | break; | 1070 | break; |
1078 | case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: | 1071 | case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: |
1079 | ret = mwifiex_cmd_ibss_coalescing_status(priv, cmd_ptr, | 1072 | ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action, |
1080 | cmd_action, data_buf); | 1073 | data_buf); |
1081 | break; | 1074 | break; |
1082 | case HostCmd_CMD_MAC_REG_ACCESS: | 1075 | case HostCmd_CMD_MAC_REG_ACCESS: |
1083 | case HostCmd_CMD_BBP_REG_ACCESS: | 1076 | case HostCmd_CMD_BBP_REG_ACCESS: |
@@ -1136,65 +1129,66 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1136 | 1129 | ||
1137 | if (first_sta) { | 1130 | if (first_sta) { |
1138 | 1131 | ||
1139 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_FUNC_INIT, | 1132 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT, |
1140 | HostCmd_ACT_GEN_SET, 0, NULL, NULL); | 1133 | HostCmd_ACT_GEN_SET, 0, NULL); |
1141 | if (ret) | 1134 | if (ret) |
1142 | return -1; | 1135 | return -1; |
1143 | /* Read MAC address from HW */ | 1136 | /* Read MAC address from HW */ |
1144 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_GET_HW_SPEC, | 1137 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_GET_HW_SPEC, |
1145 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 1138 | HostCmd_ACT_GEN_GET, 0, NULL); |
1146 | if (ret) | 1139 | if (ret) |
1147 | return -1; | 1140 | return -1; |
1148 | 1141 | ||
1149 | /* Reconfigure tx buf size */ | 1142 | /* Reconfigure tx buf size */ |
1150 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, | 1143 | ret = mwifiex_send_cmd_async(priv, |
1151 | HostCmd_ACT_GEN_SET, 0, NULL, | 1144 | HostCmd_CMD_RECONFIGURE_TX_BUFF, |
1152 | &priv->adapter->tx_buf_size); | 1145 | HostCmd_ACT_GEN_SET, 0, |
1146 | &priv->adapter->tx_buf_size); | ||
1153 | if (ret) | 1147 | if (ret) |
1154 | return -1; | 1148 | return -1; |
1155 | 1149 | ||
1156 | /* Enable IEEE PS by default */ | 1150 | /* Enable IEEE PS by default */ |
1157 | priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; | 1151 | priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; |
1158 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, | 1152 | ret = mwifiex_send_cmd_async(priv, |
1159 | EN_AUTO_PS, BITMAP_STA_PS, NULL, | 1153 | HostCmd_CMD_802_11_PS_MODE_ENH, |
1160 | NULL); | 1154 | EN_AUTO_PS, BITMAP_STA_PS, NULL); |
1161 | if (ret) | 1155 | if (ret) |
1162 | return -1; | 1156 | return -1; |
1163 | } | 1157 | } |
1164 | 1158 | ||
1165 | /* get tx rate */ | 1159 | /* get tx rate */ |
1166 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, | 1160 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG, |
1167 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 1161 | HostCmd_ACT_GEN_GET, 0, NULL); |
1168 | if (ret) | 1162 | if (ret) |
1169 | return -1; | 1163 | return -1; |
1170 | priv->data_rate = 0; | 1164 | priv->data_rate = 0; |
1171 | 1165 | ||
1172 | /* get tx power */ | 1166 | /* get tx power */ |
1173 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, | 1167 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG, |
1174 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 1168 | HostCmd_ACT_GEN_GET, 0, NULL); |
1175 | if (ret) | 1169 | if (ret) |
1176 | return -1; | 1170 | return -1; |
1177 | 1171 | ||
1178 | /* set ibss coalescing_status */ | 1172 | /* set ibss coalescing_status */ |
1179 | ret = mwifiex_prepare_cmd(priv, | 1173 | ret = mwifiex_send_cmd_async(priv, |
1180 | HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, | 1174 | HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, |
1181 | HostCmd_ACT_GEN_SET, 0, NULL, &enable); | 1175 | HostCmd_ACT_GEN_SET, 0, &enable); |
1182 | if (ret) | 1176 | if (ret) |
1183 | return -1; | 1177 | return -1; |
1184 | 1178 | ||
1185 | memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); | 1179 | memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); |
1186 | amsdu_aggr_ctrl.enable = true; | 1180 | amsdu_aggr_ctrl.enable = true; |
1187 | /* Send request to firmware */ | 1181 | /* Send request to firmware */ |
1188 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, | 1182 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, |
1189 | HostCmd_ACT_GEN_SET, 0, NULL, | 1183 | HostCmd_ACT_GEN_SET, 0, |
1190 | (void *) &amsdu_aggr_ctrl); | 1184 | (void *) &amsdu_aggr_ctrl); |
1191 | if (ret) | 1185 | if (ret) |
1192 | return -1; | 1186 | return -1; |
1193 | /* MAC Control must be the last command in init_fw */ | 1187 | /* MAC Control must be the last command in init_fw */ |
1194 | /* set MAC Control */ | 1188 | /* set MAC Control */ |
1195 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, | 1189 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
1196 | HostCmd_ACT_GEN_SET, 0, NULL, | 1190 | HostCmd_ACT_GEN_SET, 0, |
1197 | &priv->curr_pkt_filter); | 1191 | &priv->curr_pkt_filter); |
1198 | if (ret) | 1192 | if (ret) |
1199 | return -1; | 1193 | return -1; |
1200 | 1194 | ||
@@ -1202,19 +1196,18 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1202 | /* Enable auto deep sleep */ | 1196 | /* Enable auto deep sleep */ |
1203 | auto_ds.auto_ds = DEEP_SLEEP_ON; | 1197 | auto_ds.auto_ds = DEEP_SLEEP_ON; |
1204 | auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; | 1198 | auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; |
1205 | ret = mwifiex_prepare_cmd(priv, | 1199 | ret = mwifiex_send_cmd_async(priv, |
1206 | HostCmd_CMD_802_11_PS_MODE_ENH, | 1200 | HostCmd_CMD_802_11_PS_MODE_ENH, |
1207 | EN_AUTO_PS, BITMAP_AUTO_DS, NULL, | 1201 | EN_AUTO_PS, BITMAP_AUTO_DS, |
1208 | &auto_ds); | 1202 | &auto_ds); |
1209 | if (ret) | 1203 | if (ret) |
1210 | return -1; | 1204 | return -1; |
1211 | } | 1205 | } |
1212 | 1206 | ||
1213 | /* Send cmd to FW to enable/disable 11D function */ | 1207 | /* Send cmd to FW to enable/disable 11D function */ |
1214 | state_11d = ENABLE_11D; | 1208 | state_11d = ENABLE_11D; |
1215 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, | 1209 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB, |
1216 | HostCmd_ACT_GEN_SET, DOT11D_I, | 1210 | HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d); |
1217 | NULL, &state_11d); | ||
1218 | if (ret) | 1211 | if (ret) |
1219 | dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); | 1212 | dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); |
1220 | 1213 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 74add45b99b6..7f4f10b752fb 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -41,8 +41,7 @@ | |||
41 | */ | 41 | */ |
42 | static void | 42 | static void |
43 | mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | 43 | mwifiex_process_cmdresp_error(struct mwifiex_private *priv, |
44 | struct host_cmd_ds_command *resp, | 44 | struct host_cmd_ds_command *resp) |
45 | struct mwifiex_wait_queue *wq_buf) | ||
46 | { | 45 | { |
47 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; | 46 | struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; |
48 | struct mwifiex_adapter *adapter = priv->adapter; | 47 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -51,8 +50,9 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | |||
51 | 50 | ||
52 | dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", | 51 | dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", |
53 | resp->command, resp->result); | 52 | resp->command, resp->result); |
54 | if (wq_buf) | 53 | |
55 | wq_buf->status = MWIFIEX_ERROR_FW_CMDRESP; | 54 | if (adapter->curr_cmd->wait_q_enabled) |
55 | adapter->cmd_wait_q.status = -1; | ||
56 | 56 | ||
57 | switch (le16_to_cpu(resp->command)) { | 57 | switch (le16_to_cpu(resp->command)) { |
58 | case HostCmd_CMD_802_11_PS_MODE_ENH: | 58 | case HostCmd_CMD_802_11_PS_MODE_ENH: |
@@ -103,8 +103,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | |||
103 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 103 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
104 | adapter->curr_cmd = NULL; | 104 | adapter->curr_cmd = NULL; |
105 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | 105 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
106 | |||
107 | return; | ||
108 | } | 106 | } |
109 | 107 | ||
110 | /* | 108 | /* |
@@ -282,7 +280,6 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
282 | struct host_cmd_ds_command *resp, | 280 | struct host_cmd_ds_command *resp, |
283 | void *data_buf) | 281 | void *data_buf) |
284 | { | 282 | { |
285 | struct mwifiex_adapter *adapter = priv->adapter; | ||
286 | struct mwifiex_rate_cfg *ds_rate = NULL; | 283 | struct mwifiex_rate_cfg *ds_rate = NULL; |
287 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; | 284 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; |
288 | struct mwifiex_rate_scope *rate_scope; | 285 | struct mwifiex_rate_scope *rate_scope; |
@@ -328,9 +325,9 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
328 | if (priv->is_data_rate_auto) | 325 | if (priv->is_data_rate_auto) |
329 | priv->data_rate = 0; | 326 | priv->data_rate = 0; |
330 | else | 327 | else |
331 | ret = mwifiex_prepare_cmd(priv, | 328 | ret = mwifiex_send_cmd_async(priv, |
332 | HostCmd_CMD_802_11_TX_RATE_QUERY, | 329 | HostCmd_CMD_802_11_TX_RATE_QUERY, |
333 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 330 | HostCmd_ACT_GEN_GET, 0, NULL); |
334 | 331 | ||
335 | if (data_buf) { | 332 | if (data_buf) { |
336 | ds_rate = (struct mwifiex_rate_cfg *) data_buf; | 333 | ds_rate = (struct mwifiex_rate_cfg *) data_buf; |
@@ -338,9 +335,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
338 | if (priv->is_data_rate_auto) { | 335 | if (priv->is_data_rate_auto) { |
339 | ds_rate->is_rate_auto = 1; | 336 | ds_rate->is_rate_auto = 1; |
340 | } else { | 337 | } else { |
341 | ds_rate->rate = | 338 | ds_rate->rate = mwifiex_get_rate_index(priv-> |
342 | mwifiex_get_rate_index(adapter, | ||
343 | priv-> | ||
344 | bitmap_rates, | 339 | bitmap_rates, |
345 | sizeof(priv-> | 340 | sizeof(priv-> |
346 | bitmap_rates)); | 341 | bitmap_rates)); |
@@ -516,13 +511,11 @@ static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv, | |||
516 | static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv, | 511 | static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv, |
517 | struct host_cmd_ds_command *resp) | 512 | struct host_cmd_ds_command *resp) |
518 | { | 513 | { |
519 | struct mwifiex_adapter *adapter = priv->adapter; | ||
520 | |||
521 | priv->tx_rate = resp->params.tx_rate.tx_rate; | 514 | priv->tx_rate = resp->params.tx_rate.tx_rate; |
522 | priv->tx_htinfo = resp->params.tx_rate.ht_info; | 515 | priv->tx_htinfo = resp->params.tx_rate.ht_info; |
523 | if (!priv->is_data_rate_auto) | 516 | if (!priv->is_data_rate_auto) |
524 | priv->data_rate = | 517 | priv->data_rate = |
525 | mwifiex_index_to_data_rate(adapter, priv->tx_rate, | 518 | mwifiex_index_to_data_rate(priv->tx_rate, |
526 | priv->tx_htinfo); | 519 | priv->tx_htinfo); |
527 | 520 | ||
528 | return 0; | 521 | return 0; |
@@ -574,8 +567,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, | |||
574 | &resp->params.key_material; | 567 | &resp->params.key_material; |
575 | 568 | ||
576 | if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { | 569 | if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { |
577 | if ((le16_to_cpu(key->key_param_set.key_info) & | 570 | if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { |
578 | KEY_INFO_TKIP_MCAST)) { | ||
579 | dev_dbg(priv->adapter->dev, "info: key: GTK is set\n"); | 571 | dev_dbg(priv->adapter->dev, "info: key: GTK is set\n"); |
580 | priv->wpa_is_gtk_set = true; | 572 | priv->wpa_is_gtk_set = true; |
581 | priv->scan_block = false; | 573 | priv->scan_block = false; |
@@ -834,19 +826,17 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, | |||
834 | * response handlers based on the command ID. | 826 | * response handlers based on the command ID. |
835 | */ | 827 | */ |
836 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | 828 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, |
837 | u16 cmdresp_no, void *cmd_buf, void *wq_buf) | 829 | u16 cmdresp_no, void *cmd_buf) |
838 | { | 830 | { |
839 | int ret = 0; | 831 | int ret = 0; |
840 | struct mwifiex_adapter *adapter = priv->adapter; | 832 | struct mwifiex_adapter *adapter = priv->adapter; |
841 | struct host_cmd_ds_command *resp = | 833 | struct host_cmd_ds_command *resp = |
842 | (struct host_cmd_ds_command *) cmd_buf; | 834 | (struct host_cmd_ds_command *) cmd_buf; |
843 | struct mwifiex_wait_queue *wait_queue = | ||
844 | (struct mwifiex_wait_queue *) wq_buf; | ||
845 | void *data_buf = adapter->curr_cmd->data_buf; | 835 | void *data_buf = adapter->curr_cmd->data_buf; |
846 | 836 | ||
847 | /* If the command is not successful, cleanup and return failure */ | 837 | /* If the command is not successful, cleanup and return failure */ |
848 | if (resp->result != HostCmd_RESULT_OK) { | 838 | if (resp->result != HostCmd_RESULT_OK) { |
849 | mwifiex_process_cmdresp_error(priv, resp, wait_queue); | 839 | mwifiex_process_cmdresp_error(priv, resp); |
850 | return -1; | 840 | return -1; |
851 | } | 841 | } |
852 | /* Command successful, handle response */ | 842 | /* Command successful, handle response */ |
@@ -866,12 +856,11 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | |||
866 | ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); | 856 | ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); |
867 | break; | 857 | break; |
868 | case HostCmd_CMD_802_11_SCAN: | 858 | case HostCmd_CMD_802_11_SCAN: |
869 | ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); | 859 | ret = mwifiex_ret_802_11_scan(priv, resp); |
870 | wait_queue = NULL; | 860 | adapter->curr_cmd->wait_q_enabled = false; |
871 | adapter->curr_cmd->wq_buf = NULL; | ||
872 | break; | 861 | break; |
873 | case HostCmd_CMD_802_11_BG_SCAN_QUERY: | 862 | case HostCmd_CMD_802_11_BG_SCAN_QUERY: |
874 | ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); | 863 | ret = mwifiex_ret_802_11_scan(priv, resp); |
875 | dev_dbg(adapter->dev, | 864 | dev_dbg(adapter->dev, |
876 | "info: CMD_RESP: BG_SCAN result is ready!\n"); | 865 | "info: CMD_RESP: BG_SCAN result is ready!\n"); |
877 | break; | 866 | break; |
@@ -885,14 +874,14 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | |||
885 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); | 874 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); |
886 | break; | 875 | break; |
887 | case HostCmd_CMD_802_11_ASSOCIATE: | 876 | case HostCmd_CMD_802_11_ASSOCIATE: |
888 | ret = mwifiex_ret_802_11_associate(priv, resp, wait_queue); | 877 | ret = mwifiex_ret_802_11_associate(priv, resp); |
889 | break; | 878 | break; |
890 | case HostCmd_CMD_802_11_DEAUTHENTICATE: | 879 | case HostCmd_CMD_802_11_DEAUTHENTICATE: |
891 | ret = mwifiex_ret_802_11_deauthenticate(priv, resp); | 880 | ret = mwifiex_ret_802_11_deauthenticate(priv, resp); |
892 | break; | 881 | break; |
893 | case HostCmd_CMD_802_11_AD_HOC_START: | 882 | case HostCmd_CMD_802_11_AD_HOC_START: |
894 | case HostCmd_CMD_802_11_AD_HOC_JOIN: | 883 | case HostCmd_CMD_802_11_AD_HOC_JOIN: |
895 | ret = mwifiex_ret_802_11_ad_hoc(priv, resp, wait_queue); | 884 | ret = mwifiex_ret_802_11_ad_hoc(priv, resp); |
896 | break; | 885 | break; |
897 | case HostCmd_CMD_802_11_AD_HOC_STOP: | 886 | case HostCmd_CMD_802_11_AD_HOC_STOP: |
898 | ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp); | 887 | ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp); |
@@ -952,7 +941,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | |||
952 | mp_end_port)); | 941 | mp_end_port)); |
953 | break; | 942 | break; |
954 | case HostCmd_CMD_AMSDU_AGGR_CTRL: | 943 | case HostCmd_CMD_AMSDU_AGGR_CTRL: |
955 | ret = mwifiex_ret_amsdu_aggr_ctrl(priv, resp, data_buf); | 944 | ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); |
956 | break; | 945 | break; |
957 | case HostCmd_CMD_WMM_GET_STATUS: | 946 | case HostCmd_CMD_WMM_GET_STATUS: |
958 | ret = mwifiex_ret_wmm_get_status(priv, resp); | 947 | ret = mwifiex_ret_wmm_get_status(priv, resp); |
@@ -971,7 +960,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | |||
971 | case HostCmd_CMD_SET_BSS_MODE: | 960 | case HostCmd_CMD_SET_BSS_MODE: |
972 | break; | 961 | break; |
973 | case HostCmd_CMD_11N_CFG: | 962 | case HostCmd_CMD_11N_CFG: |
974 | ret = mwifiex_ret_11n_cfg(priv, resp, data_buf); | 963 | ret = mwifiex_ret_11n_cfg(resp, data_buf); |
975 | break; | 964 | break; |
976 | default: | 965 | default: |
977 | dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", | 966 | dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", |
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 936d7c175e75..fc265cab0907 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c | |||
@@ -271,8 +271,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
271 | 271 | ||
272 | case EVENT_HS_ACT_REQ: | 272 | case EVENT_HS_ACT_REQ: |
273 | dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); | 273 | dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); |
274 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, | 274 | ret = mwifiex_send_cmd_async(priv, |
275 | 0, 0, NULL, NULL); | 275 | HostCmd_CMD_802_11_HS_CFG_ENH, |
276 | 0, 0, NULL); | ||
276 | break; | 277 | break; |
277 | 278 | ||
278 | case EVENT_MIC_ERR_UNICAST: | 279 | case EVENT_MIC_ERR_UNICAST: |
@@ -303,9 +304,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
303 | sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP); | 304 | sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP); |
304 | adapter->num_in_scan_table = 0; | 305 | adapter->num_in_scan_table = 0; |
305 | adapter->bcn_buf_end = adapter->bcn_buf; | 306 | adapter->bcn_buf_end = adapter->bcn_buf; |
306 | ret = mwifiex_prepare_cmd(priv, | 307 | ret = mwifiex_send_cmd_async(priv, |
307 | HostCmd_CMD_802_11_BG_SCAN_QUERY, | 308 | HostCmd_CMD_802_11_BG_SCAN_QUERY, |
308 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 309 | HostCmd_ACT_GEN_GET, 0, NULL); |
309 | break; | 310 | break; |
310 | 311 | ||
311 | case EVENT_PORT_RELEASE: | 312 | case EVENT_PORT_RELEASE: |
@@ -314,8 +315,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
314 | 315 | ||
315 | case EVENT_WMM_STATUS_CHANGE: | 316 | case EVENT_WMM_STATUS_CHANGE: |
316 | dev_dbg(adapter->dev, "event: WMM status changed\n"); | 317 | dev_dbg(adapter->dev, "event: WMM status changed\n"); |
317 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS, | 318 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_WMM_GET_STATUS, |
318 | 0, 0, NULL, NULL); | 319 | 0, 0, NULL); |
319 | break; | 320 | break; |
320 | 321 | ||
321 | case EVENT_RSSI_LOW: | 322 | case EVENT_RSSI_LOW: |
@@ -353,15 +354,15 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
353 | break; | 354 | break; |
354 | case EVENT_IBSS_COALESCED: | 355 | case EVENT_IBSS_COALESCED: |
355 | dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); | 356 | dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); |
356 | ret = mwifiex_prepare_cmd(priv, | 357 | ret = mwifiex_send_cmd_async(priv, |
357 | HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, | 358 | HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, |
358 | HostCmd_ACT_GEN_GET, 0, NULL, NULL); | 359 | HostCmd_ACT_GEN_GET, 0, NULL); |
359 | break; | 360 | break; |
360 | case EVENT_ADDBA: | 361 | case EVENT_ADDBA: |
361 | dev_dbg(adapter->dev, "event: ADDBA Request\n"); | 362 | dev_dbg(adapter->dev, "event: ADDBA Request\n"); |
362 | mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP, | 363 | mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP, |
363 | HostCmd_ACT_GEN_SET, 0, NULL, | 364 | HostCmd_ACT_GEN_SET, 0, |
364 | adapter->event_body); | 365 | adapter->event_body); |
365 | break; | 366 | break; |
366 | case EVENT_DELBA: | 367 | case EVENT_DELBA: |
367 | dev_dbg(adapter->dev, "event: DELBA Request\n"); | 368 | dev_dbg(adapter->dev, "event: DELBA Request\n"); |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index b163507b1fe0..6489f264ef5f 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -33,9 +33,8 @@ | |||
33 | * size, and the calling function must ensure enough memory is | 33 | * size, and the calling function must ensure enough memory is |
34 | * available. | 34 | * available. |
35 | */ | 35 | */ |
36 | static int | 36 | int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, |
37 | mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, | 37 | struct net_device *dev) |
38 | struct net_device *dev) | ||
39 | { | 38 | { |
40 | int i = 0; | 39 | int i = 0; |
41 | struct netdev_hw_addr *ha; | 40 | struct netdev_hw_addr *ha; |
@@ -47,216 +46,51 @@ mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, | |||
47 | } | 46 | } |
48 | 47 | ||
49 | /* | 48 | /* |
50 | * Allocate and fills a wait queue with proper parameters. | ||
51 | * | ||
52 | * This function needs to be called before an IOCTL request can be made. | ||
53 | * It can handle the following wait options: | ||
54 | * MWIFIEX_NO_WAIT - Waiting is disabled | ||
55 | * MWIFIEX_IOCTL_WAIT - Waiting is done on IOCTL wait queue | ||
56 | * MWIFIEX_CMD_WAIT - Waiting is done on command wait queue | ||
57 | * MWIFIEX_WSTATS_WAIT - Waiting is done on stats wait queue | ||
58 | */ | ||
59 | struct mwifiex_wait_queue * | ||
60 | mwifiex_alloc_fill_wait_queue(struct mwifiex_private *priv, | ||
61 | u8 wait_option) | ||
62 | { | ||
63 | struct mwifiex_wait_queue *wait = NULL; | ||
64 | |||
65 | wait = (struct mwifiex_wait_queue *) | ||
66 | kzalloc(sizeof(struct mwifiex_wait_queue), GFP_ATOMIC); | ||
67 | if (!wait) { | ||
68 | dev_err(priv->adapter->dev, "%s: fail to alloc buffer\n", | ||
69 | __func__); | ||
70 | return wait; | ||
71 | } | ||
72 | |||
73 | wait->bss_index = priv->bss_index; | ||
74 | |||
75 | switch (wait_option) { | ||
76 | case MWIFIEX_NO_WAIT: | ||
77 | wait->enabled = 0; | ||
78 | break; | ||
79 | case MWIFIEX_IOCTL_WAIT: | ||
80 | priv->ioctl_wait_q_woken = false; | ||
81 | wait->start_time = jiffies; | ||
82 | wait->wait = &priv->ioctl_wait_q; | ||
83 | wait->condition = &priv->ioctl_wait_q_woken; | ||
84 | wait->enabled = 1; | ||
85 | break; | ||
86 | case MWIFIEX_CMD_WAIT: | ||
87 | priv->cmd_wait_q_woken = false; | ||
88 | wait->start_time = jiffies; | ||
89 | wait->wait = &priv->cmd_wait_q; | ||
90 | wait->condition = &priv->cmd_wait_q_woken; | ||
91 | wait->enabled = 1; | ||
92 | break; | ||
93 | case MWIFIEX_WSTATS_WAIT: | ||
94 | priv->w_stats_wait_q_woken = false; | ||
95 | wait->start_time = jiffies; | ||
96 | wait->wait = &priv->w_stats_wait_q; | ||
97 | wait->condition = &priv->w_stats_wait_q_woken; | ||
98 | wait->enabled = 1; | ||
99 | break; | ||
100 | } | ||
101 | |||
102 | return wait; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Wait queue completion handler. | 49 | * Wait queue completion handler. |
107 | * | 50 | * |
108 | * This function waits on a particular wait queue. | 51 | * This function waits on a cmd wait queue. It also cancels the pending |
109 | * For NO_WAIT option, it returns immediately. It also cancels the | 52 | * request after waking up, in case of errors. |
110 | * pending IOCTL request after waking up, in case of errors. | ||
111 | */ | 53 | */ |
112 | static void | 54 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) |
113 | mwifiex_wait_ioctl_complete(struct mwifiex_private *priv, | ||
114 | struct mwifiex_wait_queue *wait, | ||
115 | u8 wait_option) | ||
116 | { | 55 | { |
117 | bool cancel_flag = false; | 56 | bool cancel_flag = false; |
57 | int status = adapter->cmd_wait_q.status; | ||
118 | 58 | ||
119 | switch (wait_option) { | 59 | dev_dbg(adapter->dev, "cmd pending\n"); |
120 | case MWIFIEX_NO_WAIT: | 60 | atomic_inc(&adapter->cmd_pending); |
121 | break; | ||
122 | case MWIFIEX_IOCTL_WAIT: | ||
123 | wait_event_interruptible(priv->ioctl_wait_q, | ||
124 | priv->ioctl_wait_q_woken); | ||
125 | if (!priv->ioctl_wait_q_woken) | ||
126 | cancel_flag = true; | ||
127 | break; | ||
128 | case MWIFIEX_CMD_WAIT: | ||
129 | wait_event_interruptible(priv->cmd_wait_q, | ||
130 | priv->cmd_wait_q_woken); | ||
131 | if (!priv->cmd_wait_q_woken) | ||
132 | cancel_flag = true; | ||
133 | break; | ||
134 | case MWIFIEX_WSTATS_WAIT: | ||
135 | wait_event_interruptible(priv->w_stats_wait_q, | ||
136 | priv->w_stats_wait_q_woken); | ||
137 | if (!priv->w_stats_wait_q_woken) | ||
138 | cancel_flag = true; | ||
139 | break; | ||
140 | } | ||
141 | if (cancel_flag) { | ||
142 | mwifiex_cancel_pending_ioctl(priv->adapter, wait); | ||
143 | dev_dbg(priv->adapter->dev, "cmd: IOCTL cancel: wait=%p, wait_option=%d\n", | ||
144 | wait, wait_option); | ||
145 | } | ||
146 | 61 | ||
147 | return; | 62 | /* Status pending, wake up main process */ |
148 | } | 63 | queue_work(adapter->workqueue, &adapter->main_work); |
149 | 64 | ||
150 | /* | 65 | /* Wait for completion */ |
151 | * The function waits for the request to complete and issues the | 66 | wait_event_interruptible(adapter->cmd_wait_q.wait, |
152 | * completion handler, if required. | 67 | adapter->cmd_wait_q.condition); |
153 | */ | 68 | if (!adapter->cmd_wait_q.condition) |
154 | int mwifiex_request_ioctl(struct mwifiex_private *priv, | 69 | cancel_flag = true; |
155 | struct mwifiex_wait_queue *wait, | ||
156 | int status, u8 wait_option) | ||
157 | { | ||
158 | switch (status) { | ||
159 | case -EINPROGRESS: | ||
160 | dev_dbg(priv->adapter->dev, "cmd: IOCTL pending: wait=%p, wait_option=%d\n", | ||
161 | wait, wait_option); | ||
162 | atomic_inc(&priv->adapter->ioctl_pending); | ||
163 | /* Status pending, wake up main process */ | ||
164 | queue_work(priv->adapter->workqueue, &priv->adapter->main_work); | ||
165 | |||
166 | /* Wait for completion */ | ||
167 | if (wait_option) { | ||
168 | mwifiex_wait_ioctl_complete(priv, wait, wait_option); | ||
169 | status = wait->status; | ||
170 | } | ||
171 | break; | ||
172 | case 0: | ||
173 | case -1: | ||
174 | case -EBUSY: | ||
175 | default: | ||
176 | break; | ||
177 | } | ||
178 | return status; | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(mwifiex_request_ioctl); | ||
181 | 70 | ||
182 | /* | 71 | if (cancel_flag) { |
183 | * IOCTL request handler to set/get MAC address. | 72 | mwifiex_cancel_pending_ioctl(adapter); |
184 | * | 73 | dev_dbg(adapter->dev, "cmd cancel\n"); |
185 | * This function prepares the correct firmware command and | ||
186 | * issues it to get the extended version information. | ||
187 | */ | ||
188 | static int mwifiex_bss_ioctl_mac_address(struct mwifiex_private *priv, | ||
189 | struct mwifiex_wait_queue *wait, | ||
190 | u8 action, u8 *mac) | ||
191 | { | ||
192 | int ret = 0; | ||
193 | |||
194 | if ((action == HostCmd_ACT_GEN_GET) && mac) { | ||
195 | memcpy(mac, priv->curr_addr, ETH_ALEN); | ||
196 | return 0; | ||
197 | } | 74 | } |
75 | adapter->cmd_wait_q.status = 0; | ||
198 | 76 | ||
199 | /* Send request to firmware */ | ||
200 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS, | ||
201 | action, 0, wait, mac); | ||
202 | if (!ret) | ||
203 | ret = -EINPROGRESS; | ||
204 | |||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * Sends IOCTL request to set MAC address. | ||
210 | * | ||
211 | * This function allocates the IOCTL request buffer, fills it | ||
212 | * with requisite parameters and calls the IOCTL handler. | ||
213 | */ | ||
214 | int mwifiex_request_set_mac_address(struct mwifiex_private *priv) | ||
215 | { | ||
216 | struct mwifiex_wait_queue *wait = NULL; | ||
217 | int status = 0; | ||
218 | u8 wait_option = MWIFIEX_CMD_WAIT; | ||
219 | |||
220 | /* Allocate wait buffer */ | ||
221 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
222 | if (!wait) | ||
223 | return -ENOMEM; | ||
224 | |||
225 | status = mwifiex_bss_ioctl_mac_address(priv, wait, HostCmd_ACT_GEN_SET, | ||
226 | NULL); | ||
227 | |||
228 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
229 | if (!status) | ||
230 | memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); | ||
231 | else | ||
232 | dev_err(priv->adapter->dev, "set mac address failed: status=%d" | ||
233 | " error_code=%#x\n", status, wait->status); | ||
234 | |||
235 | kfree(wait); | ||
236 | return status; | 77 | return status; |
237 | } | 78 | } |
238 | 79 | ||
239 | /* | 80 | /* |
240 | * IOCTL request handler to set multicast list. | ||
241 | * | ||
242 | * This function prepares the correct firmware command and | 81 | * This function prepares the correct firmware command and |
243 | * issues it to set the multicast list. | 82 | * issues it to set the multicast list. |
244 | * | 83 | * |
245 | * This function can be used to enable promiscuous mode, or enable all | 84 | * This function can be used to enable promiscuous mode, or enable all |
246 | * multicast packets, or to enable selective multicast. | 85 | * multicast packets, or to enable selective multicast. |
247 | */ | 86 | */ |
248 | static int | 87 | int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, |
249 | mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, | 88 | struct mwifiex_multicast_list *mcast_list) |
250 | struct mwifiex_wait_queue *wait, | ||
251 | u16 action, | ||
252 | struct mwifiex_multicast_list *mcast_list) | ||
253 | { | 89 | { |
254 | int ret = 0; | 90 | int ret = 0; |
255 | u16 old_pkt_filter; | 91 | u16 old_pkt_filter; |
256 | 92 | ||
257 | old_pkt_filter = priv->curr_pkt_filter; | 93 | old_pkt_filter = priv->curr_pkt_filter; |
258 | if (action == HostCmd_ACT_GEN_GET) | ||
259 | return -1; | ||
260 | 94 | ||
261 | if (mcast_list->mode == MWIFIEX_PROMISC_MODE) { | 95 | if (mcast_list->mode == MWIFIEX_PROMISC_MODE) { |
262 | dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n"); | 96 | dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n"); |
@@ -281,16 +115,15 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, | |||
281 | /* Set multicast addresses to firmware */ | 115 | /* Set multicast addresses to firmware */ |
282 | if (old_pkt_filter == priv->curr_pkt_filter) { | 116 | if (old_pkt_filter == priv->curr_pkt_filter) { |
283 | /* Send request to firmware */ | 117 | /* Send request to firmware */ |
284 | ret = mwifiex_prepare_cmd(priv, | 118 | ret = mwifiex_send_cmd_async(priv, |
285 | HostCmd_CMD_MAC_MULTICAST_ADR, | 119 | HostCmd_CMD_MAC_MULTICAST_ADR, |
286 | action, 0, wait, mcast_list); | 120 | HostCmd_ACT_GEN_SET, 0, |
287 | if (!ret) | 121 | mcast_list); |
288 | ret = -EINPROGRESS; | ||
289 | } else { | 122 | } else { |
290 | /* Send request to firmware */ | 123 | /* Send request to firmware */ |
291 | ret = mwifiex_prepare_cmd(priv, | 124 | ret = mwifiex_send_cmd_async(priv, |
292 | HostCmd_CMD_MAC_MULTICAST_ADR, | 125 | HostCmd_CMD_MAC_MULTICAST_ADR, |
293 | action, 0, NULL, | 126 | HostCmd_ACT_GEN_SET, 0, |
294 | mcast_list); | 127 | mcast_list); |
295 | } | 128 | } |
296 | } | 129 | } |
@@ -300,101 +133,21 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, | |||
300 | "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", | 133 | "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", |
301 | old_pkt_filter, priv->curr_pkt_filter); | 134 | old_pkt_filter, priv->curr_pkt_filter); |
302 | if (old_pkt_filter != priv->curr_pkt_filter) { | 135 | if (old_pkt_filter != priv->curr_pkt_filter) { |
303 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, action, | 136 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
304 | 0, wait, &priv->curr_pkt_filter); | 137 | HostCmd_ACT_GEN_SET, |
305 | if (!ret) | 138 | 0, &priv->curr_pkt_filter); |
306 | ret = -EINPROGRESS; | ||
307 | } | 139 | } |
308 | 140 | ||
309 | return ret; | 141 | return ret; |
310 | } | 142 | } |
311 | 143 | ||
312 | /* | 144 | /* |
313 | * Sends IOCTL request to set multicast list. | ||
314 | * | ||
315 | * This function allocates the IOCTL request buffer, fills it | ||
316 | * with requisite parameters and calls the IOCTL handler. | ||
317 | */ | ||
318 | void | ||
319 | mwifiex_request_set_multicast_list(struct mwifiex_private *priv, | ||
320 | struct net_device *dev) | ||
321 | { | ||
322 | struct mwifiex_wait_queue *wait = NULL; | ||
323 | struct mwifiex_multicast_list mcast_list; | ||
324 | u8 wait_option = MWIFIEX_NO_WAIT; | ||
325 | int status = 0; | ||
326 | |||
327 | /* Allocate wait buffer */ | ||
328 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
329 | if (!wait) | ||
330 | return; | ||
331 | |||
332 | if (dev->flags & IFF_PROMISC) { | ||
333 | mcast_list.mode = MWIFIEX_PROMISC_MODE; | ||
334 | } else if (dev->flags & IFF_ALLMULTI || | ||
335 | netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) { | ||
336 | mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; | ||
337 | } else { | ||
338 | mcast_list.mode = MWIFIEX_MULTICAST_MODE; | ||
339 | if (netdev_mc_count(dev)) | ||
340 | mcast_list.num_multicast_addr = | ||
341 | mwifiex_copy_mcast_addr(&mcast_list, dev); | ||
342 | } | ||
343 | status = mwifiex_bss_ioctl_multicast_list(priv, wait, | ||
344 | HostCmd_ACT_GEN_SET, | ||
345 | &mcast_list); | ||
346 | |||
347 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
348 | if (wait && status != -EINPROGRESS) | ||
349 | kfree(wait); | ||
350 | |||
351 | return; | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * IOCTL request handler to disconnect from a BSS/IBSS. | ||
356 | */ | ||
357 | static int mwifiex_bss_ioctl_stop(struct mwifiex_private *priv, | ||
358 | struct mwifiex_wait_queue *wait, u8 *mac) | ||
359 | { | ||
360 | return mwifiex_deauthenticate(priv, wait, mac); | ||
361 | } | ||
362 | |||
363 | /* | ||
364 | * Sends IOCTL request to disconnect from a BSS. | ||
365 | * | ||
366 | * This function allocates the IOCTL request buffer, fills it | ||
367 | * with requisite parameters and calls the IOCTL handler. | ||
368 | */ | ||
369 | int mwifiex_disconnect(struct mwifiex_private *priv, u8 wait_option, u8 *mac) | ||
370 | { | ||
371 | struct mwifiex_wait_queue *wait = NULL; | ||
372 | int status = 0; | ||
373 | |||
374 | /* Allocate wait buffer */ | ||
375 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
376 | if (!wait) | ||
377 | return -ENOMEM; | ||
378 | |||
379 | status = mwifiex_bss_ioctl_stop(priv, wait, mac); | ||
380 | |||
381 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
382 | |||
383 | kfree(wait); | ||
384 | return status; | ||
385 | } | ||
386 | EXPORT_SYMBOL_GPL(mwifiex_disconnect); | ||
387 | |||
388 | /* | ||
389 | * IOCTL request handler to join a BSS/IBSS. | ||
390 | * | ||
391 | * In Ad-Hoc mode, the IBSS is created if not found in scan list. | 145 | * In Ad-Hoc mode, the IBSS is created if not found in scan list. |
392 | * In both Ad-Hoc and infra mode, an deauthentication is performed | 146 | * In both Ad-Hoc and infra mode, an deauthentication is performed |
393 | * first. | 147 | * first. |
394 | */ | 148 | */ |
395 | static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | 149 | int mwifiex_bss_start(struct mwifiex_private *priv, |
396 | struct mwifiex_wait_queue *wait, | 150 | struct mwifiex_ssid_bssid *ssid_bssid) |
397 | struct mwifiex_ssid_bssid *ssid_bssid) | ||
398 | { | 151 | { |
399 | int ret = 0; | 152 | int ret = 0; |
400 | struct mwifiex_adapter *adapter = priv->adapter; | 153 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -406,7 +159,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | |||
406 | 159 | ||
407 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 160 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { |
408 | /* Infra mode */ | 161 | /* Infra mode */ |
409 | ret = mwifiex_deauthenticate(priv, NULL, NULL); | 162 | ret = mwifiex_deauthenticate(priv, NULL); |
410 | if (ret) | 163 | if (ret) |
411 | return ret; | 164 | return ret; |
412 | 165 | ||
@@ -427,7 +180,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | |||
427 | /* Clear any past association response stored for | 180 | /* Clear any past association response stored for |
428 | * application retrieval */ | 181 | * application retrieval */ |
429 | priv->assoc_rsp_size = 0; | 182 | priv->assoc_rsp_size = 0; |
430 | ret = mwifiex_associate(priv, wait, &adapter->scan_table[i]); | 183 | ret = mwifiex_associate(priv, &adapter->scan_table[i]); |
431 | if (ret) | 184 | if (ret) |
432 | return ret; | 185 | return ret; |
433 | } else { | 186 | } else { |
@@ -441,7 +194,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | |||
441 | 194 | ||
442 | /* Exit Adhoc mode first */ | 195 | /* Exit Adhoc mode first */ |
443 | dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); | 196 | dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); |
444 | ret = mwifiex_deauthenticate(priv, NULL, NULL); | 197 | ret = mwifiex_deauthenticate(priv, NULL); |
445 | if (ret) | 198 | if (ret) |
446 | return ret; | 199 | return ret; |
447 | 200 | ||
@@ -460,75 +213,39 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, | |||
460 | if (i >= 0) { | 213 | if (i >= 0) { |
461 | dev_dbg(adapter->dev, "info: network found in scan" | 214 | dev_dbg(adapter->dev, "info: network found in scan" |
462 | " list. Joining...\n"); | 215 | " list. Joining...\n"); |
463 | ret = mwifiex_adhoc_join(priv, wait, | 216 | ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]); |
464 | &adapter->scan_table[i]); | ||
465 | if (ret) | 217 | if (ret) |
466 | return ret; | 218 | return ret; |
467 | } else { /* i >= 0 */ | 219 | } else { /* i >= 0 */ |
468 | dev_dbg(adapter->dev, "info: Network not found in " | 220 | dev_dbg(adapter->dev, "info: Network not found in " |
469 | "the list, creating adhoc with ssid = %s\n", | 221 | "the list, creating adhoc with ssid = %s\n", |
470 | ssid_bssid->ssid.ssid); | 222 | ssid_bssid->ssid.ssid); |
471 | ret = mwifiex_adhoc_start(priv, wait, | 223 | ret = mwifiex_adhoc_start(priv, &ssid_bssid->ssid); |
472 | &ssid_bssid->ssid); | ||
473 | if (ret) | 224 | if (ret) |
474 | return ret; | 225 | return ret; |
475 | } | 226 | } |
476 | } | 227 | } |
477 | 228 | ||
478 | if (!ret) | ||
479 | ret = -EINPROGRESS; | ||
480 | |||
481 | return ret; | 229 | return ret; |
482 | } | 230 | } |
483 | 231 | ||
484 | /* | 232 | /* |
485 | * Sends IOCTL request to connect with a BSS. | ||
486 | * | ||
487 | * This function allocates the IOCTL request buffer, fills it | ||
488 | * with requisite parameters and calls the IOCTL handler. | ||
489 | */ | ||
490 | int mwifiex_bss_start(struct mwifiex_private *priv, u8 wait_option, | ||
491 | struct mwifiex_ssid_bssid *ssid_bssid) | ||
492 | { | ||
493 | struct mwifiex_wait_queue *wait = NULL; | ||
494 | struct mwifiex_ssid_bssid tmp_ssid_bssid; | ||
495 | int status = 0; | ||
496 | |||
497 | /* Stop the O.S. TX queue if needed */ | ||
498 | if (!netif_queue_stopped(priv->netdev)) | ||
499 | netif_stop_queue(priv->netdev); | ||
500 | |||
501 | /* Allocate wait buffer */ | ||
502 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
503 | if (!wait) | ||
504 | return -ENOMEM; | ||
505 | |||
506 | if (ssid_bssid) | ||
507 | memcpy(&tmp_ssid_bssid, ssid_bssid, | ||
508 | sizeof(struct mwifiex_ssid_bssid)); | ||
509 | status = mwifiex_bss_ioctl_start(priv, wait, &tmp_ssid_bssid); | ||
510 | |||
511 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
512 | |||
513 | kfree(wait); | ||
514 | return status; | ||
515 | } | ||
516 | |||
517 | /* | ||
518 | * IOCTL request handler to set host sleep configuration. | 233 | * IOCTL request handler to set host sleep configuration. |
519 | * | 234 | * |
520 | * This function prepares the correct firmware command and | 235 | * This function prepares the correct firmware command and |
521 | * issues it. | 236 | * issues it. |
522 | */ | 237 | */ |
523 | static int | 238 | int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, |
524 | mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, | 239 | int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) |
525 | struct mwifiex_wait_queue *wait, | 240 | |
526 | u16 action, struct mwifiex_ds_hs_cfg *hs_cfg) | ||
527 | { | 241 | { |
528 | struct mwifiex_adapter *adapter = priv->adapter; | 242 | struct mwifiex_adapter *adapter = priv->adapter; |
529 | int status = 0; | 243 | int status = 0; |
530 | u32 prev_cond = 0; | 244 | u32 prev_cond = 0; |
531 | 245 | ||
246 | if (!hs_cfg) | ||
247 | return -ENOMEM; | ||
248 | |||
532 | switch (action) { | 249 | switch (action) { |
533 | case HostCmd_ACT_GEN_SET: | 250 | case HostCmd_ACT_GEN_SET: |
534 | if (adapter->pps_uapsd_mode) { | 251 | if (adapter->pps_uapsd_mode) { |
@@ -561,12 +278,16 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, | |||
561 | status = -1; | 278 | status = -1; |
562 | break; | 279 | break; |
563 | } | 280 | } |
564 | status = mwifiex_prepare_cmd(priv, | 281 | if (cmd_type == MWIFIEX_SYNC_CMD) |
565 | HostCmd_CMD_802_11_HS_CFG_ENH, | 282 | status = mwifiex_send_cmd_sync(priv, |
566 | HostCmd_ACT_GEN_SET, | 283 | HostCmd_CMD_802_11_HS_CFG_ENH, |
567 | 0, wait, &adapter->hs_cfg); | 284 | HostCmd_ACT_GEN_SET, 0, |
568 | if (!status) | 285 | &adapter->hs_cfg); |
569 | status = -EINPROGRESS; | 286 | else |
287 | status = mwifiex_send_cmd_async(priv, | ||
288 | HostCmd_CMD_802_11_HS_CFG_ENH, | ||
289 | HostCmd_ACT_GEN_SET, 0, | ||
290 | &adapter->hs_cfg); | ||
570 | if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) | 291 | if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) |
571 | /* Restore previous condition */ | 292 | /* Restore previous condition */ |
572 | adapter->hs_cfg.conditions = | 293 | adapter->hs_cfg.conditions = |
@@ -592,42 +313,12 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, | |||
592 | } | 313 | } |
593 | 314 | ||
594 | /* | 315 | /* |
595 | * Sends IOCTL request to set Host Sleep parameters. | ||
596 | * | ||
597 | * This function allocates the IOCTL request buffer, fills it | ||
598 | * with requisite parameters and calls the IOCTL handler. | ||
599 | */ | ||
600 | int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, | ||
601 | u8 wait_option, | ||
602 | struct mwifiex_ds_hs_cfg *hscfg) | ||
603 | { | ||
604 | int ret = 0; | ||
605 | struct mwifiex_wait_queue *wait = NULL; | ||
606 | |||
607 | if (!hscfg) | ||
608 | return -ENOMEM; | ||
609 | |||
610 | /* Allocate wait buffer */ | ||
611 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
612 | if (!wait) | ||
613 | return -ENOMEM; | ||
614 | |||
615 | ret = mwifiex_pm_ioctl_hs_cfg(priv, wait, action, hscfg); | ||
616 | |||
617 | ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); | ||
618 | |||
619 | if (wait && (ret != -EINPROGRESS)) | ||
620 | kfree(wait); | ||
621 | return ret; | ||
622 | } | ||
623 | |||
624 | /* | ||
625 | * Sends IOCTL request to cancel the existing Host Sleep configuration. | 316 | * Sends IOCTL request to cancel the existing Host Sleep configuration. |
626 | * | 317 | * |
627 | * This function allocates the IOCTL request buffer, fills it | 318 | * This function allocates the IOCTL request buffer, fills it |
628 | * with requisite parameters and calls the IOCTL handler. | 319 | * with requisite parameters and calls the IOCTL handler. |
629 | */ | 320 | */ |
630 | int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option) | 321 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type) |
631 | { | 322 | { |
632 | int ret = 0; | 323 | int ret = 0; |
633 | struct mwifiex_ds_hs_cfg hscfg; | 324 | struct mwifiex_ds_hs_cfg hscfg; |
@@ -636,7 +327,7 @@ int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option) | |||
636 | hscfg.conditions = HOST_SLEEP_CFG_CANCEL; | 327 | hscfg.conditions = HOST_SLEEP_CFG_CANCEL; |
637 | hscfg.is_invoke_hostcmd = true; | 328 | hscfg.is_invoke_hostcmd = true; |
638 | ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, | 329 | ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, |
639 | wait_option, &hscfg); | 330 | cmd_type, &hscfg); |
640 | 331 | ||
641 | return ret; | 332 | return ret; |
642 | } | 333 | } |
@@ -665,8 +356,8 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
665 | 356 | ||
666 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, | 357 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, |
667 | MWIFIEX_BSS_ROLE_STA), | 358 | MWIFIEX_BSS_ROLE_STA), |
668 | HostCmd_ACT_GEN_SET, | 359 | HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, |
669 | MWIFIEX_IOCTL_WAIT, &hscfg)) { | 360 | &hscfg)) { |
670 | dev_err(adapter->dev, "IOCTL request HS enable failed\n"); | 361 | dev_err(adapter->dev, "IOCTL request HS enable failed\n"); |
671 | return false; | 362 | return false; |
672 | } | 363 | } |
@@ -679,69 +370,6 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
679 | EXPORT_SYMBOL_GPL(mwifiex_enable_hs); | 370 | EXPORT_SYMBOL_GPL(mwifiex_enable_hs); |
680 | 371 | ||
681 | /* | 372 | /* |
682 | * IOCTL request handler to get signal information. | ||
683 | * | ||
684 | * This function prepares the correct firmware command and | ||
685 | * issues it to get the signal (RSSI) information. | ||
686 | * | ||
687 | * This only works in the connected mode. | ||
688 | */ | ||
689 | static int mwifiex_get_info_signal(struct mwifiex_private *priv, | ||
690 | struct mwifiex_wait_queue *wait, | ||
691 | struct mwifiex_ds_get_signal *signal) | ||
692 | { | ||
693 | int ret = 0; | ||
694 | |||
695 | if (!wait) { | ||
696 | dev_err(priv->adapter->dev, "WAIT information is not present\n"); | ||
697 | return -1; | ||
698 | } | ||
699 | |||
700 | /* Signal info can be obtained only if connected */ | ||
701 | if (!priv->media_connected) { | ||
702 | dev_dbg(priv->adapter->dev, | ||
703 | "info: Can not get signal in disconnected state\n"); | ||
704 | return -1; | ||
705 | } | ||
706 | |||
707 | /* Send request to firmware */ | ||
708 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RSSI_INFO, | ||
709 | HostCmd_ACT_GEN_GET, 0, wait, signal); | ||
710 | |||
711 | if (!ret) | ||
712 | ret = -EINPROGRESS; | ||
713 | |||
714 | return ret; | ||
715 | } | ||
716 | |||
717 | /* | ||
718 | * IOCTL request handler to get statistics. | ||
719 | * | ||
720 | * This function prepares the correct firmware command and | ||
721 | * issues it to get the statistics (RSSI) information. | ||
722 | */ | ||
723 | static int mwifiex_get_info_stats(struct mwifiex_private *priv, | ||
724 | struct mwifiex_wait_queue *wait, | ||
725 | struct mwifiex_ds_get_stats *log) | ||
726 | { | ||
727 | int ret = 0; | ||
728 | |||
729 | if (!wait) { | ||
730 | dev_err(priv->adapter->dev, "MWIFIEX IOCTL information is not present\n"); | ||
731 | return -1; | ||
732 | } | ||
733 | |||
734 | /* Send request to firmware */ | ||
735 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_GET_LOG, | ||
736 | HostCmd_ACT_GEN_GET, 0, wait, log); | ||
737 | |||
738 | if (!ret) | ||
739 | ret = -EINPROGRESS; | ||
740 | |||
741 | return ret; | ||
742 | } | ||
743 | |||
744 | /* | ||
745 | * IOCTL request handler to get BSS information. | 373 | * IOCTL request handler to get BSS information. |
746 | * | 374 | * |
747 | * This function collates the information from different driver structures | 375 | * This function collates the information from different driver structures |
@@ -813,90 +441,20 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, | |||
813 | } | 441 | } |
814 | 442 | ||
815 | /* | 443 | /* |
816 | * IOCTL request handler to get extended version information. | 444 | * The function sets band configurations. |
817 | * | ||
818 | * This function prepares the correct firmware command and | ||
819 | * issues it to get the extended version information. | ||
820 | */ | ||
821 | static int mwifiex_get_info_ver_ext(struct mwifiex_private *priv, | ||
822 | struct mwifiex_wait_queue *wait, | ||
823 | struct mwifiex_ver_ext *ver_ext) | ||
824 | { | ||
825 | int ret = 0; | ||
826 | |||
827 | /* Send request to firmware */ | ||
828 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_VERSION_EXT, | ||
829 | HostCmd_ACT_GEN_GET, 0, wait, ver_ext); | ||
830 | if (!ret) | ||
831 | ret = -EINPROGRESS; | ||
832 | |||
833 | return ret; | ||
834 | } | ||
835 | |||
836 | /* | ||
837 | * IOCTL request handler to set/get SNMP MIB parameters. | ||
838 | * | ||
839 | * This function prepares the correct firmware command and | ||
840 | * issues it. | ||
841 | * | 445 | * |
842 | * Currently the following parameters are supported - | 446 | * it performs extra checks to make sure the Ad-Hoc |
843 | * Set/get RTS Threshold | ||
844 | * Set/get fragmentation threshold | ||
845 | * Set/get retry count | ||
846 | */ | ||
847 | int mwifiex_snmp_mib_ioctl(struct mwifiex_private *priv, | ||
848 | struct mwifiex_wait_queue *wait, | ||
849 | u32 cmd_oid, u16 action, u32 *value) | ||
850 | { | ||
851 | int ret = 0; | ||
852 | |||
853 | if (!value) | ||
854 | return -1; | ||
855 | |||
856 | /* Send request to firmware */ | ||
857 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, | ||
858 | action, cmd_oid, wait, value); | ||
859 | |||
860 | if (!ret) | ||
861 | ret = -EINPROGRESS; | ||
862 | |||
863 | return ret; | ||
864 | } | ||
865 | |||
866 | /* | ||
867 | * IOCTL request handler to set/get band configurations. | ||
868 | * | ||
869 | * For SET operation, it performs extra checks to make sure the Ad-Hoc | ||
870 | * band and channel are compatible. Otherwise it returns an error. | 447 | * band and channel are compatible. Otherwise it returns an error. |
871 | * | 448 | * |
872 | * For GET operation, this function retrieves the following information - | ||
873 | * - Infra bands | ||
874 | * - Ad-hoc band | ||
875 | * - Ad-hoc channel | ||
876 | * - Secondary channel offset | ||
877 | */ | 449 | */ |
878 | int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, | 450 | int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv, |
879 | u16 action, | 451 | struct mwifiex_ds_band_cfg *radio_cfg) |
880 | struct mwifiex_ds_band_cfg *radio_cfg) | ||
881 | { | 452 | { |
882 | struct mwifiex_adapter *adapter = priv->adapter; | 453 | struct mwifiex_adapter *adapter = priv->adapter; |
883 | u8 infra_band = 0; | 454 | u8 infra_band = 0; |
884 | u8 adhoc_band = 0; | 455 | u8 adhoc_band = 0; |
885 | u32 adhoc_channel = 0; | 456 | u32 adhoc_channel = 0; |
886 | 457 | ||
887 | if (action == HostCmd_ACT_GEN_GET) { | ||
888 | /* Infra Bands */ | ||
889 | radio_cfg->config_bands = adapter->config_bands; | ||
890 | /* Adhoc Band */ | ||
891 | radio_cfg->adhoc_start_band = adapter->adhoc_start_band; | ||
892 | /* Adhoc channel */ | ||
893 | radio_cfg->adhoc_channel = priv->adhoc_channel; | ||
894 | /* Secondary channel offset */ | ||
895 | radio_cfg->sec_chan_offset = adapter->chan_offset; | ||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | /* For action = SET */ | ||
900 | infra_band = (u8) radio_cfg->config_bands; | 458 | infra_band = (u8) radio_cfg->config_bands; |
901 | adhoc_band = (u8) radio_cfg->adhoc_start_band; | 459 | adhoc_band = (u8) radio_cfg->adhoc_start_band; |
902 | adhoc_channel = radio_cfg->adhoc_channel; | 460 | adhoc_channel = radio_cfg->adhoc_channel; |
@@ -950,8 +508,8 @@ int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, | |||
950 | * This function performs validity checking on channel/frequency | 508 | * This function performs validity checking on channel/frequency |
951 | * compatibility and returns failure if not valid. | 509 | * compatibility and returns failure if not valid. |
952 | */ | 510 | */ |
953 | int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, | 511 | int mwifiex_bss_set_channel(struct mwifiex_private *priv, |
954 | struct mwifiex_chan_freq_power *chan) | 512 | struct mwifiex_chan_freq_power *chan) |
955 | { | 513 | { |
956 | struct mwifiex_adapter *adapter = priv->adapter; | 514 | struct mwifiex_adapter *adapter = priv->adapter; |
957 | struct mwifiex_chan_freq_power *cfp = NULL; | 515 | struct mwifiex_chan_freq_power *cfp = NULL; |
@@ -959,16 +517,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, | |||
959 | if (!chan) | 517 | if (!chan) |
960 | return -1; | 518 | return -1; |
961 | 519 | ||
962 | if (action == HostCmd_ACT_GEN_GET) { | ||
963 | cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, | ||
964 | priv->curr_bss_params.band, | ||
965 | (u16) priv->curr_bss_params.bss_descriptor. | ||
966 | channel); | ||
967 | chan->channel = cfp->channel; | ||
968 | chan->freq = cfp->freq; | ||
969 | |||
970 | return 0; | ||
971 | } | ||
972 | if (!chan->channel && !chan->freq) | 520 | if (!chan->channel && !chan->freq) |
973 | return -1; | 521 | return -1; |
974 | if (adapter->adhoc_start_band & BAND_AN) | 522 | if (adapter->adhoc_start_band & BAND_AN) |
@@ -1024,7 +572,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, | |||
1024 | * issues it to set or get the ad-hoc channel. | 572 | * issues it to set or get the ad-hoc channel. |
1025 | */ | 573 | */ |
1026 | static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | 574 | static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, |
1027 | struct mwifiex_wait_queue *wait, | ||
1028 | u16 action, u16 *channel) | 575 | u16 action, u16 *channel) |
1029 | { | 576 | { |
1030 | int ret = 0; | 577 | int ret = 0; |
@@ -1039,10 +586,8 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | |||
1039 | } | 586 | } |
1040 | 587 | ||
1041 | /* Send request to firmware */ | 588 | /* Send request to firmware */ |
1042 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_RF_CHANNEL, | 589 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, |
1043 | action, 0, wait, channel); | 590 | action, 0, channel); |
1044 | if (!ret) | ||
1045 | ret = -EINPROGRESS; | ||
1046 | 591 | ||
1047 | return ret; | 592 | return ret; |
1048 | } | 593 | } |
@@ -1054,7 +599,6 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | |||
1054 | * these are provided, just the best BSS (best RSSI) is returned. | 599 | * these are provided, just the best BSS (best RSSI) is returned. |
1055 | */ | 600 | */ |
1056 | int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, | 601 | int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, |
1057 | struct mwifiex_wait_queue *wait, | ||
1058 | struct mwifiex_ssid_bssid *ssid_bssid) | 602 | struct mwifiex_ssid_bssid *ssid_bssid) |
1059 | { | 603 | { |
1060 | struct mwifiex_adapter *adapter = priv->adapter; | 604 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -1114,10 +658,7 @@ int | |||
1114 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | 658 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) |
1115 | { | 659 | { |
1116 | int ret = 0; | 660 | int ret = 0; |
1117 | int status = 0; | ||
1118 | struct mwifiex_bss_info bss_info; | 661 | struct mwifiex_bss_info bss_info; |
1119 | struct mwifiex_wait_queue *wait = NULL; | ||
1120 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
1121 | struct mwifiex_ssid_bssid ssid_bssid; | 662 | struct mwifiex_ssid_bssid ssid_bssid; |
1122 | u16 curr_chan = 0; | 663 | u16 curr_chan = 0; |
1123 | 664 | ||
@@ -1127,19 +668,10 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
1127 | if (mwifiex_get_bss_info(priv, &bss_info)) | 668 | if (mwifiex_get_bss_info(priv, &bss_info)) |
1128 | return -1; | 669 | return -1; |
1129 | 670 | ||
1130 | /* Allocate wait buffer */ | ||
1131 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1132 | if (!wait) | ||
1133 | return -ENOMEM; | ||
1134 | |||
1135 | /* Get current channel */ | 671 | /* Get current channel */ |
1136 | status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_GET, | 672 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_GET, |
1137 | &curr_chan); | 673 | &curr_chan); |
1138 | 674 | ||
1139 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { | ||
1140 | ret = -1; | ||
1141 | goto done; | ||
1142 | } | ||
1143 | if (curr_chan == channel) { | 675 | if (curr_chan == channel) { |
1144 | ret = 0; | 676 | ret = 0; |
1145 | goto done; | 677 | goto done; |
@@ -1154,23 +686,13 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
1154 | 686 | ||
1155 | /* Do disonnect */ | 687 | /* Do disonnect */ |
1156 | memset(&ssid_bssid, 0, ETH_ALEN); | 688 | memset(&ssid_bssid, 0, ETH_ALEN); |
1157 | status = mwifiex_bss_ioctl_stop(priv, wait, ssid_bssid.bssid); | 689 | ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); |
1158 | 690 | ||
1159 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { | 691 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, |
1160 | ret = -1; | 692 | (u16 *) &channel); |
1161 | goto done; | ||
1162 | } | ||
1163 | |||
1164 | status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_SET, | ||
1165 | (u16 *) &channel); | ||
1166 | |||
1167 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { | ||
1168 | ret = -1; | ||
1169 | goto done; | ||
1170 | } | ||
1171 | 693 | ||
1172 | /* Do specific SSID scanning */ | 694 | /* Do specific SSID scanning */ |
1173 | if (mwifiex_request_scan(priv, wait_option, &bss_info.ssid)) { | 695 | if (mwifiex_request_scan(priv, &bss_info.ssid)) { |
1174 | ret = -1; | 696 | ret = -1; |
1175 | goto done; | 697 | goto done; |
1176 | } | 698 | } |
@@ -1179,13 +701,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
1179 | memcpy(&ssid_bssid.ssid, &bss_info.ssid, | 701 | memcpy(&ssid_bssid.ssid, &bss_info.ssid, |
1180 | sizeof(struct mwifiex_802_11_ssid)); | 702 | sizeof(struct mwifiex_802_11_ssid)); |
1181 | 703 | ||
1182 | status = mwifiex_bss_ioctl_start(priv, wait, &ssid_bssid); | 704 | ret = mwifiex_bss_start(priv, &ssid_bssid); |
1183 | |||
1184 | if (mwifiex_request_ioctl(priv, wait, status, wait_option)) | ||
1185 | ret = -1; | ||
1186 | |||
1187 | done: | 705 | done: |
1188 | kfree(wait); | ||
1189 | return ret; | 706 | return ret; |
1190 | } | 707 | } |
1191 | 708 | ||
@@ -1198,7 +715,6 @@ done: | |||
1198 | * for the band. | 715 | * for the band. |
1199 | */ | 716 | */ |
1200 | static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, | 717 | static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, |
1201 | struct mwifiex_wait_queue *wait, | ||
1202 | struct mwifiex_rate_cfg *rate_cfg) | 718 | struct mwifiex_rate_cfg *rate_cfg) |
1203 | { | 719 | { |
1204 | struct mwifiex_adapter *adapter = priv->adapter; | 720 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -1242,11 +758,9 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, | |||
1242 | } | 758 | } |
1243 | } else { | 759 | } else { |
1244 | /* Send request to firmware */ | 760 | /* Send request to firmware */ |
1245 | ret = mwifiex_prepare_cmd(priv, | 761 | ret = mwifiex_send_cmd_sync(priv, |
1246 | HostCmd_CMD_802_11_TX_RATE_QUERY, | 762 | HostCmd_CMD_802_11_TX_RATE_QUERY, |
1247 | HostCmd_ACT_GEN_GET, 0, wait, NULL); | 763 | HostCmd_ACT_GEN_GET, 0, NULL); |
1248 | if (!ret) | ||
1249 | ret = -EINPROGRESS; | ||
1250 | } | 764 | } |
1251 | 765 | ||
1252 | return ret; | 766 | return ret; |
@@ -1261,7 +775,6 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, | |||
1261 | * The function also performs validation checking on the supplied value. | 775 | * The function also performs validation checking on the supplied value. |
1262 | */ | 776 | */ |
1263 | static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, | 777 | static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, |
1264 | struct mwifiex_wait_queue *wait, | ||
1265 | struct mwifiex_rate_cfg *rate_cfg) | 778 | struct mwifiex_rate_cfg *rate_cfg) |
1266 | { | 779 | { |
1267 | u8 rates[MWIFIEX_SUPPORTED_RATES]; | 780 | u8 rates[MWIFIEX_SUPPORTED_RATES]; |
@@ -1299,8 +812,7 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, | |||
1299 | } | 812 | } |
1300 | memset(bitmap_rates, 0, sizeof(bitmap_rates)); | 813 | memset(bitmap_rates, 0, sizeof(bitmap_rates)); |
1301 | 814 | ||
1302 | rate_index = | 815 | rate_index = mwifiex_data_rate_to_index(rate_cfg->rate); |
1303 | mwifiex_data_rate_to_index(adapter, rate_cfg->rate); | ||
1304 | 816 | ||
1305 | /* Only allow b/g rates to be set */ | 817 | /* Only allow b/g rates to be set */ |
1306 | if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && | 818 | if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && |
@@ -1316,10 +828,8 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, | |||
1316 | } | 828 | } |
1317 | 829 | ||
1318 | /* Send request to firmware */ | 830 | /* Send request to firmware */ |
1319 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, | 831 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, |
1320 | HostCmd_ACT_GEN_SET, 0, wait, bitmap_rates); | 832 | HostCmd_ACT_GEN_SET, 0, bitmap_rates); |
1321 | if (!ret) | ||
1322 | ret = -EINPROGRESS; | ||
1323 | 833 | ||
1324 | return ret; | 834 | return ret; |
1325 | } | 835 | } |
@@ -1331,7 +841,6 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, | |||
1331 | * rate index. | 841 | * rate index. |
1332 | */ | 842 | */ |
1333 | static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, | 843 | static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, |
1334 | struct mwifiex_wait_queue *wait, | ||
1335 | struct mwifiex_rate_cfg *rate_cfg) | 844 | struct mwifiex_rate_cfg *rate_cfg) |
1336 | { | 845 | { |
1337 | int status = 0; | 846 | int status = 0; |
@@ -1340,11 +849,9 @@ static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, | |||
1340 | return -1; | 849 | return -1; |
1341 | 850 | ||
1342 | if (rate_cfg->action == HostCmd_ACT_GEN_GET) | 851 | if (rate_cfg->action == HostCmd_ACT_GEN_GET) |
1343 | status = mwifiex_rate_ioctl_get_rate_value( | 852 | status = mwifiex_rate_ioctl_get_rate_value(priv, rate_cfg); |
1344 | priv, wait, rate_cfg); | ||
1345 | else | 853 | else |
1346 | status = mwifiex_rate_ioctl_set_rate_value( | 854 | status = mwifiex_rate_ioctl_set_rate_value(priv, rate_cfg); |
1347 | priv, wait, rate_cfg); | ||
1348 | 855 | ||
1349 | return status; | 856 | return status; |
1350 | } | 857 | } |
@@ -1359,30 +866,21 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | |||
1359 | struct mwifiex_rate_cfg *rate) | 866 | struct mwifiex_rate_cfg *rate) |
1360 | { | 867 | { |
1361 | int ret = 0; | 868 | int ret = 0; |
1362 | struct mwifiex_wait_queue *wait = NULL; | ||
1363 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
1364 | |||
1365 | /* Allocate wait buffer */ | ||
1366 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1367 | if (!wait) | ||
1368 | return -ENOMEM; | ||
1369 | 869 | ||
1370 | memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); | 870 | memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); |
1371 | rate->action = HostCmd_ACT_GEN_GET; | 871 | rate->action = HostCmd_ACT_GEN_GET; |
1372 | ret = mwifiex_rate_ioctl_cfg(priv, wait, rate); | 872 | ret = mwifiex_rate_ioctl_cfg(priv, rate); |
1373 | 873 | ||
1374 | ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); | ||
1375 | if (!ret) { | 874 | if (!ret) { |
1376 | if (rate && rate->is_rate_auto) | 875 | if (rate && rate->is_rate_auto) |
1377 | rate->rate = mwifiex_index_to_data_rate(priv->adapter, | 876 | rate->rate = mwifiex_index_to_data_rate(priv->tx_rate, |
1378 | priv->tx_rate, priv->tx_htinfo); | 877 | priv->tx_htinfo); |
1379 | else if (rate) | 878 | else if (rate) |
1380 | rate->rate = priv->data_rate; | 879 | rate->rate = priv->data_rate; |
1381 | } else { | 880 | } else { |
1382 | ret = -1; | 881 | ret = -1; |
1383 | } | 882 | } |
1384 | 883 | ||
1385 | kfree(wait); | ||
1386 | return ret; | 884 | return ret; |
1387 | } | 885 | } |
1388 | 886 | ||
@@ -1398,9 +896,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | |||
1398 | * - Modulation class HTBW20 | 896 | * - Modulation class HTBW20 |
1399 | * - Modulation class HTBW40 | 897 | * - Modulation class HTBW40 |
1400 | */ | 898 | */ |
1401 | static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, | 899 | int mwifiex_set_tx_power(struct mwifiex_private *priv, |
1402 | struct mwifiex_wait_queue *wait, | 900 | struct mwifiex_power_cfg *power_cfg) |
1403 | struct mwifiex_power_cfg *power_cfg) | ||
1404 | { | 901 | { |
1405 | int ret = 0; | 902 | int ret = 0; |
1406 | struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL; | 903 | struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL; |
@@ -1473,12 +970,10 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, | |||
1473 | pg->ht_bandwidth = HT_BW_40; | 970 | pg->ht_bandwidth = HT_BW_40; |
1474 | } | 971 | } |
1475 | /* Send request to firmware */ | 972 | /* Send request to firmware */ |
1476 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, | 973 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG, |
1477 | HostCmd_ACT_GEN_SET, 0, wait, buf); | 974 | HostCmd_ACT_GEN_SET, 0, buf); |
1478 | if (!ret) | ||
1479 | ret = -EINPROGRESS; | ||
1480 | kfree(buf); | ||
1481 | 975 | ||
976 | kfree(buf); | ||
1482 | return ret; | 977 | return ret; |
1483 | } | 978 | } |
1484 | 979 | ||
@@ -1488,33 +983,23 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, | |||
1488 | * This function prepares the correct firmware command and | 983 | * This function prepares the correct firmware command and |
1489 | * issues it. | 984 | * issues it. |
1490 | */ | 985 | */ |
1491 | static int mwifiex_pm_ioctl_ps_mode(struct mwifiex_private *priv, | 986 | int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) |
1492 | struct mwifiex_wait_queue *wait, | ||
1493 | u32 *ps_mode, u16 action) | ||
1494 | { | 987 | { |
1495 | int ret = 0; | 988 | int ret = 0; |
1496 | struct mwifiex_adapter *adapter = priv->adapter; | 989 | struct mwifiex_adapter *adapter = priv->adapter; |
1497 | u16 sub_cmd; | 990 | u16 sub_cmd; |
1498 | 991 | ||
1499 | if (action == HostCmd_ACT_GEN_SET) { | 992 | if (*ps_mode) |
1500 | if (*ps_mode) | 993 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; |
1501 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; | 994 | else |
1502 | else | 995 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; |
1503 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; | 996 | sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; |
1504 | sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; | 997 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, |
1505 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, | 998 | sub_cmd, BITMAP_STA_PS, NULL); |
1506 | sub_cmd, BITMAP_STA_PS, wait, NULL); | 999 | if ((!ret) && (sub_cmd == DIS_AUTO_PS)) |
1507 | if ((!ret) && (sub_cmd == DIS_AUTO_PS)) | 1000 | ret = mwifiex_send_cmd_async(priv, |
1508 | ret = mwifiex_prepare_cmd(priv, | 1001 | HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, |
1509 | HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, | 1002 | 0, NULL); |
1510 | 0, NULL, NULL); | ||
1511 | } else { | ||
1512 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, | ||
1513 | GET_PS, 0, wait, NULL); | ||
1514 | } | ||
1515 | |||
1516 | if (!ret) | ||
1517 | ret = -EINPROGRESS; | ||
1518 | 1003 | ||
1519 | return ret; | 1004 | return ret; |
1520 | } | 1005 | } |
@@ -1600,18 +1085,14 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, | |||
1600 | * This function prepares the correct firmware command and | 1085 | * This function prepares the correct firmware command and |
1601 | * issues it. | 1086 | * issues it. |
1602 | */ | 1087 | */ |
1603 | static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, | 1088 | static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, |
1604 | struct mwifiex_wait_queue *wait, | ||
1605 | struct mwifiex_ds_encrypt_key *encrypt_key) | 1089 | struct mwifiex_ds_encrypt_key *encrypt_key) |
1606 | { | 1090 | { |
1607 | int ret = 0; | 1091 | int ret = 0; |
1608 | struct mwifiex_private *priv = adapter->priv[wait->bss_index]; | ||
1609 | 1092 | ||
1610 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1093 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, |
1611 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1094 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, |
1612 | wait, encrypt_key); | 1095 | encrypt_key); |
1613 | if (!ret) | ||
1614 | ret = -EINPROGRESS; | ||
1615 | 1096 | ||
1616 | return ret; | 1097 | return ret; |
1617 | } | 1098 | } |
@@ -1622,12 +1103,10 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, | |||
1622 | * This function prepares the correct firmware command and | 1103 | * This function prepares the correct firmware command and |
1623 | * issues it, after validation checks. | 1104 | * issues it, after validation checks. |
1624 | */ | 1105 | */ |
1625 | static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | 1106 | static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, |
1626 | struct mwifiex_wait_queue *wait, | ||
1627 | struct mwifiex_ds_encrypt_key *encrypt_key) | 1107 | struct mwifiex_ds_encrypt_key *encrypt_key) |
1628 | { | 1108 | { |
1629 | int ret = 0; | 1109 | int ret = 0; |
1630 | struct mwifiex_private *priv = adapter->priv[wait->bss_index]; | ||
1631 | struct mwifiex_wep_key *wep_key = NULL; | 1110 | struct mwifiex_wep_key *wep_key = NULL; |
1632 | int index; | 1111 | int index; |
1633 | 1112 | ||
@@ -1641,7 +1120,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | |||
1641 | /* Copy the required key as the current key */ | 1120 | /* Copy the required key as the current key */ |
1642 | wep_key = &priv->wep_key[index]; | 1121 | wep_key = &priv->wep_key[index]; |
1643 | if (!wep_key->key_length) { | 1122 | if (!wep_key->key_length) { |
1644 | dev_err(adapter->dev, | 1123 | dev_err(priv->adapter->dev, |
1645 | "key not set, so cannot enable it\n"); | 1124 | "key not set, so cannot enable it\n"); |
1646 | return -1; | 1125 | return -1; |
1647 | } | 1126 | } |
@@ -1661,8 +1140,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | |||
1661 | } | 1140 | } |
1662 | if (wep_key->key_length) { | 1141 | if (wep_key->key_length) { |
1663 | /* Send request to firmware */ | 1142 | /* Send request to firmware */ |
1664 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1143 | ret = mwifiex_send_cmd_async(priv, |
1665 | HostCmd_ACT_GEN_SET, 0, NULL, NULL); | 1144 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1145 | HostCmd_ACT_GEN_SET, 0, NULL); | ||
1666 | if (ret) | 1146 | if (ret) |
1667 | return ret; | 1147 | return ret; |
1668 | } | 1148 | } |
@@ -1672,11 +1152,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | |||
1672 | priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; | 1152 | priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; |
1673 | 1153 | ||
1674 | /* Send request to firmware */ | 1154 | /* Send request to firmware */ |
1675 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, | 1155 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, |
1676 | HostCmd_ACT_GEN_SET, 0, wait, | 1156 | HostCmd_ACT_GEN_SET, 0, |
1677 | &priv->curr_pkt_filter); | 1157 | &priv->curr_pkt_filter); |
1678 | if (!ret) | ||
1679 | ret = -EINPROGRESS; | ||
1680 | 1158 | ||
1681 | return ret; | 1159 | return ret; |
1682 | } | 1160 | } |
@@ -1691,18 +1169,16 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, | |||
1691 | * | 1169 | * |
1692 | * This function can also be used to disable a currently set key. | 1170 | * This function can also be used to disable a currently set key. |
1693 | */ | 1171 | */ |
1694 | static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | 1172 | static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, |
1695 | struct mwifiex_wait_queue *wait, | ||
1696 | struct mwifiex_ds_encrypt_key *encrypt_key) | 1173 | struct mwifiex_ds_encrypt_key *encrypt_key) |
1697 | { | 1174 | { |
1698 | int ret = 0; | 1175 | int ret = 0; |
1699 | struct mwifiex_private *priv = adapter->priv[wait->bss_index]; | ||
1700 | u8 remove_key = false; | 1176 | u8 remove_key = false; |
1701 | struct host_cmd_ds_802_11_key_material *ibss_key; | 1177 | struct host_cmd_ds_802_11_key_material *ibss_key; |
1702 | 1178 | ||
1703 | /* Current driver only supports key length of up to 32 bytes */ | 1179 | /* Current driver only supports key length of up to 32 bytes */ |
1704 | if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) { | 1180 | if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) { |
1705 | dev_err(adapter->dev, "key length too long\n"); | 1181 | dev_err(priv->adapter->dev, "key length too long\n"); |
1706 | return -1; | 1182 | return -1; |
1707 | } | 1183 | } |
1708 | 1184 | ||
@@ -1713,9 +1189,10 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | |||
1713 | */ | 1189 | */ |
1714 | /* Send the key as PTK to firmware */ | 1190 | /* Send the key as PTK to firmware */ |
1715 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; | 1191 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; |
1716 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1192 | ret = mwifiex_send_cmd_async(priv, |
1717 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1193 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1718 | NULL, encrypt_key); | 1194 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, |
1195 | encrypt_key); | ||
1719 | if (ret) | 1196 | if (ret) |
1720 | return ret; | 1197 | return ret; |
1721 | 1198 | ||
@@ -1729,8 +1206,7 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | |||
1729 | sizeof(ibss_key->key_param_set.key_len)); | 1206 | sizeof(ibss_key->key_param_set.key_len)); |
1730 | ibss_key->key_param_set.key_type_id | 1207 | ibss_key->key_param_set.key_type_id |
1731 | = cpu_to_le16(KEY_TYPE_ID_TKIP); | 1208 | = cpu_to_le16(KEY_TYPE_ID_TKIP); |
1732 | ibss_key->key_param_set.key_info | 1209 | ibss_key->key_param_set.key_info = cpu_to_le16(KEY_ENABLED); |
1733 | = cpu_to_le16(KEY_INFO_TKIP_ENABLED); | ||
1734 | 1210 | ||
1735 | /* Send the key as GTK to firmware */ | 1211 | /* Send the key as GTK to firmware */ |
1736 | encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST; | 1212 | encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST; |
@@ -1741,18 +1217,16 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | |||
1741 | 1217 | ||
1742 | if (remove_key) | 1218 | if (remove_key) |
1743 | /* Send request to firmware */ | 1219 | /* Send request to firmware */ |
1744 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1220 | ret = mwifiex_send_cmd_sync(priv, |
1745 | HostCmd_ACT_GEN_SET, | 1221 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1746 | !(KEY_INFO_ENABLED), | 1222 | HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), |
1747 | wait, encrypt_key); | 1223 | encrypt_key); |
1748 | else | 1224 | else |
1749 | /* Send request to firmware */ | 1225 | /* Send request to firmware */ |
1750 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1226 | ret = mwifiex_send_cmd_sync(priv, |
1751 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1227 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1752 | wait, encrypt_key); | 1228 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, |
1753 | 1229 | encrypt_key); | |
1754 | if (!ret) | ||
1755 | ret = -EINPROGRESS; | ||
1756 | 1230 | ||
1757 | return ret; | 1231 | return ret; |
1758 | } | 1232 | } |
@@ -1765,21 +1239,16 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, | |||
1765 | */ | 1239 | */ |
1766 | static int | 1240 | static int |
1767 | mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, | 1241 | mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, |
1768 | struct mwifiex_wait_queue *wait, | ||
1769 | struct mwifiex_ds_encrypt_key *encrypt_key) | 1242 | struct mwifiex_ds_encrypt_key *encrypt_key) |
1770 | { | 1243 | { |
1771 | int status = 0; | 1244 | int status = 0; |
1772 | struct mwifiex_adapter *adapter = priv->adapter; | ||
1773 | 1245 | ||
1774 | if (encrypt_key->is_wapi_key) | 1246 | if (encrypt_key->is_wapi_key) |
1775 | status = mwifiex_sec_ioctl_set_wapi_key(adapter, wait, | 1247 | status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key); |
1776 | encrypt_key); | ||
1777 | else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104) | 1248 | else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104) |
1778 | status = mwifiex_sec_ioctl_set_wpa_key(adapter, wait, | 1249 | status = mwifiex_sec_ioctl_set_wpa_key(priv, encrypt_key); |
1779 | encrypt_key); | ||
1780 | else | 1250 | else |
1781 | status = mwifiex_sec_ioctl_set_wep_key(adapter, wait, | 1251 | status = mwifiex_sec_ioctl_set_wep_key(priv, encrypt_key); |
1782 | encrypt_key); | ||
1783 | return status; | 1252 | return status; |
1784 | } | 1253 | } |
1785 | 1254 | ||
@@ -1807,94 +1276,31 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, | |||
1807 | } | 1276 | } |
1808 | 1277 | ||
1809 | /* | 1278 | /* |
1810 | * Sends IOCTL request to set Tx power. It can be set to either auto | ||
1811 | * or a fixed value. | ||
1812 | * | ||
1813 | * This function allocates the IOCTL request buffer, fills it | ||
1814 | * with requisite parameters and calls the IOCTL handler. | ||
1815 | */ | ||
1816 | int | ||
1817 | mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm) | ||
1818 | { | ||
1819 | struct mwifiex_power_cfg power_cfg; | ||
1820 | struct mwifiex_wait_queue *wait = NULL; | ||
1821 | int status = 0; | ||
1822 | int ret = 0; | ||
1823 | |||
1824 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
1825 | if (!wait) | ||
1826 | return -ENOMEM; | ||
1827 | |||
1828 | if (type == NL80211_TX_POWER_FIXED) { | ||
1829 | power_cfg.is_power_auto = 0; | ||
1830 | power_cfg.power_level = dbm; | ||
1831 | } else { | ||
1832 | power_cfg.is_power_auto = 1; | ||
1833 | } | ||
1834 | status = mwifiex_power_ioctl_set_power(priv, wait, &power_cfg); | ||
1835 | |||
1836 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | ||
1837 | |||
1838 | kfree(wait); | ||
1839 | return ret; | ||
1840 | } | ||
1841 | |||
1842 | /* | ||
1843 | * Sends IOCTL request to get scan table. | ||
1844 | * | ||
1845 | * This function allocates the IOCTL request buffer, fills it | ||
1846 | * with requisite parameters and calls the IOCTL handler. | ||
1847 | */ | ||
1848 | int mwifiex_get_scan_table(struct mwifiex_private *priv, u8 wait_option, | ||
1849 | struct mwifiex_scan_resp *scan_resp) | ||
1850 | { | ||
1851 | struct mwifiex_wait_queue *wait = NULL; | ||
1852 | struct mwifiex_scan_resp scan; | ||
1853 | int status = 0; | ||
1854 | |||
1855 | /* Allocate wait buffer */ | ||
1856 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1857 | if (!wait) | ||
1858 | return -ENOMEM; | ||
1859 | |||
1860 | status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_GET, | ||
1861 | NULL, &scan); | ||
1862 | |||
1863 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
1864 | if (!status) { | ||
1865 | if (scan_resp) | ||
1866 | memcpy(scan_resp, &scan, | ||
1867 | sizeof(struct mwifiex_scan_resp)); | ||
1868 | } | ||
1869 | |||
1870 | if (wait && (status != -EINPROGRESS)) | ||
1871 | kfree(wait); | ||
1872 | return status; | ||
1873 | } | ||
1874 | |||
1875 | /* | ||
1876 | * Sends IOCTL request to get signal information. | 1279 | * Sends IOCTL request to get signal information. |
1877 | * | 1280 | * |
1878 | * This function allocates the IOCTL request buffer, fills it | 1281 | * This function allocates the IOCTL request buffer, fills it |
1879 | * with requisite parameters and calls the IOCTL handler. | 1282 | * with requisite parameters and calls the IOCTL handler. |
1880 | */ | 1283 | */ |
1881 | int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, | 1284 | int mwifiex_get_signal_info(struct mwifiex_private *priv, |
1882 | struct mwifiex_ds_get_signal *signal) | 1285 | struct mwifiex_ds_get_signal *signal) |
1883 | { | 1286 | { |
1884 | struct mwifiex_ds_get_signal info; | 1287 | struct mwifiex_ds_get_signal info; |
1885 | struct mwifiex_wait_queue *wait = NULL; | ||
1886 | int status = 0; | 1288 | int status = 0; |
1887 | 1289 | ||
1888 | /* Allocate wait buffer */ | 1290 | memset(&info, 0, sizeof(struct mwifiex_ds_get_signal)); |
1889 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1890 | if (!wait) | ||
1891 | return -ENOMEM; | ||
1892 | |||
1893 | info.selector = ALL_RSSI_INFO_MASK; | 1291 | info.selector = ALL_RSSI_INFO_MASK; |
1894 | 1292 | ||
1895 | status = mwifiex_get_info_signal(priv, wait, &info); | 1293 | /* Signal info can be obtained only if connected */ |
1294 | if (!priv->media_connected) { | ||
1295 | dev_dbg(priv->adapter->dev, | ||
1296 | "info: Can not get signal in disconnected state\n"); | ||
1297 | return -1; | ||
1298 | } | ||
1299 | |||
1300 | /* Send request to firmware */ | ||
1301 | status = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO, | ||
1302 | HostCmd_ACT_GEN_GET, 0, signal); | ||
1896 | 1303 | ||
1897 | status = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
1898 | if (!status) { | 1304 | if (!status) { |
1899 | if (signal) | 1305 | if (signal) |
1900 | memcpy(signal, &info, | 1306 | memcpy(signal, &info, |
@@ -1905,8 +1311,6 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, | |||
1905 | priv->w_stats.qual.noise = info.bcn_nf_avg; | 1311 | priv->w_stats.qual.noise = info.bcn_nf_avg; |
1906 | } | 1312 | } |
1907 | 1313 | ||
1908 | if (wait && (status != -EINPROGRESS)) | ||
1909 | kfree(wait); | ||
1910 | return status; | 1314 | return status; |
1911 | } | 1315 | } |
1912 | 1316 | ||
@@ -1919,15 +1323,9 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, | |||
1919 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, | 1323 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, |
1920 | int key_len, u8 key_index, int disable) | 1324 | int key_len, u8 key_index, int disable) |
1921 | { | 1325 | { |
1922 | struct mwifiex_wait_queue *wait = NULL; | ||
1923 | struct mwifiex_ds_encrypt_key encrypt_key; | 1326 | struct mwifiex_ds_encrypt_key encrypt_key; |
1924 | int status = 0; | ||
1925 | int ret = 0; | 1327 | int ret = 0; |
1926 | 1328 | ||
1927 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
1928 | if (!wait) | ||
1929 | return -ENOMEM; | ||
1930 | |||
1931 | memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); | 1329 | memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); |
1932 | encrypt_key.key_len = key_len; | 1330 | encrypt_key.key_len = key_len; |
1933 | if (!disable) { | 1331 | if (!disable) { |
@@ -1938,40 +1336,8 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, | |||
1938 | encrypt_key.key_disable = true; | 1336 | encrypt_key.key_disable = true; |
1939 | } | 1337 | } |
1940 | 1338 | ||
1941 | status = mwifiex_sec_ioctl_encrypt_key(priv, wait, &encrypt_key); | 1339 | ret = mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); |
1942 | |||
1943 | if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT)) | ||
1944 | ret = -EFAULT; | ||
1945 | |||
1946 | kfree(wait); | ||
1947 | return ret; | ||
1948 | } | ||
1949 | |||
1950 | /* | ||
1951 | * Sends IOCTL request to set power management parameters. | ||
1952 | * | ||
1953 | * This function allocates the IOCTL request buffer, fills it | ||
1954 | * with requisite parameters and calls the IOCTL handler. | ||
1955 | */ | ||
1956 | int | ||
1957 | mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on) | ||
1958 | { | ||
1959 | int ret = 0; | ||
1960 | int status = 0; | ||
1961 | struct mwifiex_wait_queue *wait = NULL; | ||
1962 | u32 ps_mode; | ||
1963 | |||
1964 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
1965 | if (!wait) | ||
1966 | return -ENOMEM; | ||
1967 | |||
1968 | ps_mode = power_on; | ||
1969 | status = mwifiex_pm_ioctl_ps_mode(priv, wait, &ps_mode, | ||
1970 | HostCmd_ACT_GEN_SET); | ||
1971 | 1340 | ||
1972 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | ||
1973 | |||
1974 | kfree(wait); | ||
1975 | return ret; | 1341 | return ret; |
1976 | } | 1342 | } |
1977 | 1343 | ||
@@ -1985,26 +1351,17 @@ int | |||
1985 | mwifiex_get_ver_ext(struct mwifiex_private *priv) | 1351 | mwifiex_get_ver_ext(struct mwifiex_private *priv) |
1986 | { | 1352 | { |
1987 | struct mwifiex_ver_ext ver_ext; | 1353 | struct mwifiex_ver_ext ver_ext; |
1988 | struct mwifiex_wait_queue *wait = NULL; | ||
1989 | int status = 0; | ||
1990 | int ret = 0; | 1354 | int ret = 0; |
1991 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
1992 | |||
1993 | /* Allocate wait buffer */ | ||
1994 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
1995 | if (!wait) | ||
1996 | return -ENOMEM; | ||
1997 | 1355 | ||
1998 | /* get fw version */ | 1356 | /* get fw version */ |
1999 | memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); | 1357 | memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); |
2000 | status = mwifiex_get_info_ver_ext(priv, wait, &ver_ext); | 1358 | /* Send request to firmware */ |
2001 | 1359 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, | |
2002 | ret = mwifiex_request_ioctl(priv, wait, status, wait_option); | 1360 | HostCmd_ACT_GEN_GET, 0, &ver_ext); |
2003 | 1361 | ||
2004 | if (ret) | 1362 | if (ret) |
2005 | ret = -1; | 1363 | ret = -1; |
2006 | 1364 | ||
2007 | kfree(wait); | ||
2008 | return ret; | 1365 | return ret; |
2009 | } | 1366 | } |
2010 | 1367 | ||
@@ -2019,21 +1376,13 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, | |||
2019 | struct mwifiex_ds_get_stats *log) | 1376 | struct mwifiex_ds_get_stats *log) |
2020 | { | 1377 | { |
2021 | int ret = 0; | 1378 | int ret = 0; |
2022 | int status = 0; | ||
2023 | struct mwifiex_wait_queue *wait = NULL; | ||
2024 | struct mwifiex_ds_get_stats get_log; | 1379 | struct mwifiex_ds_get_stats get_log; |
2025 | u8 wait_option = MWIFIEX_IOCTL_WAIT; | ||
2026 | |||
2027 | /* Allocate wait buffer */ | ||
2028 | wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); | ||
2029 | if (!wait) | ||
2030 | return -ENOMEM; | ||
2031 | 1380 | ||
2032 | memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats)); | 1381 | memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats)); |
2033 | status = mwifiex_get_info_stats(priv, wait, &get_log); | 1382 | /* Send request to firmware */ |
1383 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, | ||
1384 | HostCmd_ACT_GEN_GET, 0, &get_log); | ||
2034 | 1385 | ||
2035 | /* Send IOCTL request to MWIFIEX */ | ||
2036 | ret = mwifiex_request_ioctl(priv, wait, status, wait_option); | ||
2037 | if (!ret) { | 1386 | if (!ret) { |
2038 | if (log) | 1387 | if (log) |
2039 | memcpy(log, &get_log, sizeof(struct | 1388 | memcpy(log, &get_log, sizeof(struct |
@@ -2043,7 +1392,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, | |||
2043 | priv->w_stats.discard.misc = get_log.ack_failure; | 1392 | priv->w_stats.discard.misc = get_log.ack_failure; |
2044 | } | 1393 | } |
2045 | 1394 | ||
2046 | kfree(wait); | ||
2047 | return ret; | 1395 | return ret; |
2048 | } | 1396 | } |
2049 | 1397 | ||
@@ -2061,7 +1409,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, | |||
2061 | * - CAU | 1409 | * - CAU |
2062 | */ | 1410 | */ |
2063 | static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, | 1411 | static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, |
2064 | struct mwifiex_wait_queue *wait, | ||
2065 | struct mwifiex_ds_reg_rw *reg_rw, | 1412 | struct mwifiex_ds_reg_rw *reg_rw, |
2066 | u16 action) | 1413 | u16 action) |
2067 | { | 1414 | { |
@@ -2089,10 +1436,7 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, | |||
2089 | } | 1436 | } |
2090 | 1437 | ||
2091 | /* Send request to firmware */ | 1438 | /* Send request to firmware */ |
2092 | ret = mwifiex_prepare_cmd(priv, cmd_no, action, 0, wait, reg_rw); | 1439 | ret = mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); |
2093 | |||
2094 | if (!ret) | ||
2095 | ret = -EINPROGRESS; | ||
2096 | 1440 | ||
2097 | return ret; | 1441 | return ret; |
2098 | } | 1442 | } |
@@ -2108,23 +1452,13 @@ mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, | |||
2108 | u32 reg_offset, u32 reg_value) | 1452 | u32 reg_offset, u32 reg_value) |
2109 | { | 1453 | { |
2110 | int ret = 0; | 1454 | int ret = 0; |
2111 | int status = 0; | ||
2112 | struct mwifiex_wait_queue *wait = NULL; | ||
2113 | struct mwifiex_ds_reg_rw reg_rw; | 1455 | struct mwifiex_ds_reg_rw reg_rw; |
2114 | 1456 | ||
2115 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
2116 | if (!wait) | ||
2117 | return -ENOMEM; | ||
2118 | |||
2119 | reg_rw.type = cpu_to_le32(reg_type); | 1457 | reg_rw.type = cpu_to_le32(reg_type); |
2120 | reg_rw.offset = cpu_to_le32(reg_offset); | 1458 | reg_rw.offset = cpu_to_le32(reg_offset); |
2121 | reg_rw.value = cpu_to_le32(reg_value); | 1459 | reg_rw.value = cpu_to_le32(reg_value); |
2122 | status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, | 1460 | ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); |
2123 | HostCmd_ACT_GEN_SET); | ||
2124 | 1461 | ||
2125 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | ||
2126 | |||
2127 | kfree(wait); | ||
2128 | return ret; | 1462 | return ret; |
2129 | } | 1463 | } |
2130 | 1464 | ||
@@ -2139,50 +1473,18 @@ mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, | |||
2139 | u32 reg_offset, u32 *value) | 1473 | u32 reg_offset, u32 *value) |
2140 | { | 1474 | { |
2141 | int ret = 0; | 1475 | int ret = 0; |
2142 | int status = 0; | ||
2143 | struct mwifiex_wait_queue *wait = NULL; | ||
2144 | struct mwifiex_ds_reg_rw reg_rw; | 1476 | struct mwifiex_ds_reg_rw reg_rw; |
2145 | 1477 | ||
2146 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
2147 | if (!wait) | ||
2148 | return -ENOMEM; | ||
2149 | |||
2150 | reg_rw.type = cpu_to_le32(reg_type); | 1478 | reg_rw.type = cpu_to_le32(reg_type); |
2151 | reg_rw.offset = cpu_to_le32(reg_offset); | 1479 | reg_rw.offset = cpu_to_le32(reg_offset); |
2152 | status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, | 1480 | ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_GET); |
2153 | HostCmd_ACT_GEN_GET); | ||
2154 | 1481 | ||
2155 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | ||
2156 | if (ret) | 1482 | if (ret) |
2157 | goto done; | 1483 | goto done; |
2158 | 1484 | ||
2159 | *value = le32_to_cpu(reg_rw.value); | 1485 | *value = le32_to_cpu(reg_rw.value); |
2160 | 1486 | ||
2161 | done: | 1487 | done: |
2162 | kfree(wait); | ||
2163 | return ret; | ||
2164 | } | ||
2165 | |||
2166 | /* | ||
2167 | * IOCTL request handler to read EEPROM. | ||
2168 | * | ||
2169 | * This function prepares the correct firmware command and | ||
2170 | * issues it. | ||
2171 | */ | ||
2172 | static int | ||
2173 | mwifiex_reg_mem_ioctl_read_eeprom(struct mwifiex_private *priv, | ||
2174 | struct mwifiex_wait_queue *wait, | ||
2175 | struct mwifiex_ds_read_eeprom *rd_eeprom) | ||
2176 | { | ||
2177 | int ret = 0; | ||
2178 | |||
2179 | /* Send request to firmware */ | ||
2180 | ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, | ||
2181 | HostCmd_ACT_GEN_GET, 0, wait, rd_eeprom); | ||
2182 | |||
2183 | if (!ret) | ||
2184 | ret = -EINPROGRESS; | ||
2185 | |||
2186 | return ret; | 1488 | return ret; |
2187 | } | 1489 | } |
2188 | 1490 | ||
@@ -2197,25 +1499,17 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, | |||
2197 | u8 *value) | 1499 | u8 *value) |
2198 | { | 1500 | { |
2199 | int ret = 0; | 1501 | int ret = 0; |
2200 | int status = 0; | ||
2201 | struct mwifiex_wait_queue *wait = NULL; | ||
2202 | struct mwifiex_ds_read_eeprom rd_eeprom; | 1502 | struct mwifiex_ds_read_eeprom rd_eeprom; |
2203 | 1503 | ||
2204 | wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); | ||
2205 | if (!wait) | ||
2206 | return -ENOMEM; | ||
2207 | |||
2208 | rd_eeprom.offset = cpu_to_le16((u16) offset); | 1504 | rd_eeprom.offset = cpu_to_le16((u16) offset); |
2209 | rd_eeprom.byte_count = cpu_to_le16((u16) bytes); | 1505 | rd_eeprom.byte_count = cpu_to_le16((u16) bytes); |
2210 | status = mwifiex_reg_mem_ioctl_read_eeprom(priv, wait, &rd_eeprom); | ||
2211 | 1506 | ||
2212 | ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); | 1507 | /* Send request to firmware */ |
2213 | if (ret) | 1508 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, |
2214 | goto done; | 1509 | HostCmd_ACT_GEN_GET, 0, &rd_eeprom); |
2215 | 1510 | ||
2216 | memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); | 1511 | if (!ret) |
2217 | done: | 1512 | memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); |
2218 | kfree(wait); | ||
2219 | return ret; | 1513 | return ret; |
2220 | } | 1514 | } |
2221 | 1515 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index e8db6bd021c6..b261d812c4d3 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c | |||
@@ -51,7 +51,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, | |||
51 | if (!skb->len) { | 51 | if (!skb->len) { |
52 | dev_err(adapter->dev, "Tx: bad packet length: %d\n", | 52 | dev_err(adapter->dev, "Tx: bad packet length: %d\n", |
53 | skb->len); | 53 | skb->len); |
54 | tx_info->status_code = MWIFIEX_ERROR_PKT_SIZE_INVALID; | 54 | tx_info->status_code = -1; |
55 | return skb->data; | 55 | return skb->data; |
56 | } | 56 | } |
57 | 57 | ||
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 205022aa52f5..9f65587622fd 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c | |||
@@ -55,17 +55,12 @@ int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * IOCTL request handler to send function init/shutdown command | 58 | * This function sends init/shutdown command |
59 | * to firmware. | 59 | * to firmware. |
60 | * | ||
61 | * This function prepares the correct firmware command and | ||
62 | * issues it. | ||
63 | */ | 60 | */ |
64 | int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, | 61 | int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, |
65 | struct mwifiex_wait_queue *wait, | 62 | u32 func_init_shutdown) |
66 | u32 func_init_shutdown) | ||
67 | { | 63 | { |
68 | struct mwifiex_private *priv = adapter->priv[wait->bss_index]; | ||
69 | int ret; | 64 | int ret; |
70 | u16 cmd; | 65 | u16 cmd; |
71 | 66 | ||
@@ -74,19 +69,16 @@ int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, | |||
74 | } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) { | 69 | } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) { |
75 | cmd = HostCmd_CMD_FUNC_SHUTDOWN; | 70 | cmd = HostCmd_CMD_FUNC_SHUTDOWN; |
76 | } else { | 71 | } else { |
77 | dev_err(adapter->dev, "unsupported parameter\n"); | 72 | dev_err(priv->adapter->dev, "unsupported parameter\n"); |
78 | return -1; | 73 | return -1; |
79 | } | 74 | } |
80 | 75 | ||
81 | /* Send command to firmware */ | 76 | /* Send command to firmware */ |
82 | ret = mwifiex_prepare_cmd(priv, cmd, HostCmd_ACT_GEN_SET, | 77 | ret = mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL); |
83 | 0, wait, NULL); | ||
84 | |||
85 | if (!ret) | ||
86 | ret = -EINPROGRESS; | ||
87 | 78 | ||
88 | return ret; | 79 | return ret; |
89 | } | 80 | } |
81 | EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw); | ||
90 | 82 | ||
91 | /* | 83 | /* |
92 | * IOCTL request handler to set/get debug information. | 84 | * IOCTL request handler to set/get debug information. |
@@ -222,31 +214,18 @@ int mwifiex_recv_complete(struct mwifiex_adapter *adapter, | |||
222 | * corresponding waiting function. Otherwise, it processes the | 214 | * corresponding waiting function. Otherwise, it processes the |
223 | * IOCTL response and frees the response buffer. | 215 | * IOCTL response and frees the response buffer. |
224 | */ | 216 | */ |
225 | int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, | 217 | int mwifiex_complete_cmd(struct mwifiex_adapter *adapter) |
226 | struct mwifiex_wait_queue *wait_queue, | ||
227 | int status) | ||
228 | { | 218 | { |
229 | enum mwifiex_error_code status_code = | 219 | atomic_dec(&adapter->cmd_pending); |
230 | (enum mwifiex_error_code) wait_queue->status; | 220 | dev_dbg(adapter->dev, "cmd completed: status=%d\n", |
231 | 221 | adapter->cmd_wait_q.status); | |
232 | atomic_dec(&adapter->ioctl_pending); | ||
233 | 222 | ||
234 | dev_dbg(adapter->dev, "cmd: IOCTL completed: status=%d," | 223 | adapter->cmd_wait_q.condition = true; |
235 | " status_code=%#x\n", status, status_code); | ||
236 | 224 | ||
237 | if (wait_queue->enabled) { | 225 | if (adapter->cmd_wait_q.status == -ETIMEDOUT) |
238 | *wait_queue->condition = true; | 226 | dev_err(adapter->dev, "cmd timeout\n"); |
239 | wait_queue->status = status; | 227 | else |
240 | if (status && (status_code == MWIFIEX_ERROR_CMD_TIMEOUT)) | 228 | wake_up_interruptible(&adapter->cmd_wait_q.wait); |
241 | dev_err(adapter->dev, "cmd timeout\n"); | ||
242 | else | ||
243 | wake_up_interruptible(wait_queue->wait); | ||
244 | } else { | ||
245 | if (status) | ||
246 | dev_err(adapter->dev, "cmd failed: status_code=%#x\n", | ||
247 | status_code); | ||
248 | kfree(wait_queue); | ||
249 | } | ||
250 | 229 | ||
251 | return 0; | 230 | return 0; |
252 | } | 231 | } |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 1cfbc6bed692..99e8431c1e93 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -177,8 +177,7 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) | |||
177 | * This function map ACs to TIDs. | 177 | * This function map ACs to TIDs. |
178 | */ | 178 | */ |
179 | static void | 179 | static void |
180 | mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv, | 180 | mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) |
181 | u8 queue_priority[]) | ||
182 | { | 181 | { |
183 | int i; | 182 | int i; |
184 | 183 | ||
@@ -247,7 +246,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, | |||
247 | } | 246 | } |
248 | } | 247 | } |
249 | 248 | ||
250 | mwifiex_wmm_queue_priorities_tid(priv, priv->wmm.queue_priority); | 249 | mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority); |
251 | } | 250 | } |
252 | 251 | ||
253 | /* | 252 | /* |
@@ -416,7 +415,7 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) | |||
416 | priv = adapter->priv[j]; | 415 | priv = adapter->priv[j]; |
417 | if (priv) { | 416 | if (priv) { |
418 | for (i = 0; i < MAX_NUM_TID; i++) | 417 | for (i = 0; i < MAX_NUM_TID; i++) |
419 | if (!mwifiex_wmm_is_ra_list_empty(adapter, | 418 | if (!mwifiex_wmm_is_ra_list_empty( |
420 | &priv->wmm.tid_tbl_ptr[i].ra_list)) | 419 | &priv->wmm.tid_tbl_ptr[i].ra_list)) |
421 | return false; | 420 | return false; |
422 | } | 421 | } |
@@ -1161,7 +1160,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) | |||
1161 | if (!ptr) | 1160 | if (!ptr) |
1162 | return -1; | 1161 | return -1; |
1163 | 1162 | ||
1164 | tid = mwifiex_get_tid(priv->adapter, ptr); | 1163 | tid = mwifiex_get_tid(ptr); |
1165 | 1164 | ||
1166 | dev_dbg(adapter->dev, "data: tid=%d\n", tid); | 1165 | dev_dbg(adapter->dev, "data: tid=%d\n", tid); |
1167 | 1166 | ||
@@ -1186,14 +1185,14 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) | |||
1186 | /* ra_list_spinlock has been freed in | 1185 | /* ra_list_spinlock has been freed in |
1187 | mwifiex_send_single_packet() */ | 1186 | mwifiex_send_single_packet() */ |
1188 | } else { | 1187 | } else { |
1189 | if (mwifiex_is_ampdu_allowed(priv, ptr, tid)) { | 1188 | if (mwifiex_is_ampdu_allowed(priv, tid)) { |
1190 | if (mwifiex_is_ba_stream_avail(priv)) { | 1189 | if (mwifiex_space_avail_for_new_ba_stream(adapter)) { |
1191 | mwifiex_11n_create_tx_ba_stream_tbl(priv, | 1190 | mwifiex_11n_create_tx_ba_stream_tbl(priv, |
1192 | ptr->ra, tid, | 1191 | ptr->ra, tid, |
1193 | BA_STREAM_SETUP_INPROGRESS); | 1192 | BA_STREAM_SETUP_INPROGRESS); |
1194 | mwifiex_send_addba(priv, tid, ptr->ra); | 1193 | mwifiex_send_addba(priv, tid, ptr->ra); |
1195 | } else if (mwifiex_find_stream_to_delete | 1194 | } else if (mwifiex_find_stream_to_delete |
1196 | (priv, ptr, tid, &tid_del, ra)) { | 1195 | (priv, tid, &tid_del, ra)) { |
1197 | mwifiex_11n_create_tx_ba_stream_tbl(priv, | 1196 | mwifiex_11n_create_tx_ba_stream_tbl(priv, |
1198 | ptr->ra, tid, | 1197 | ptr->ra, tid, |
1199 | BA_STREAM_SETUP_INPROGRESS); | 1198 | BA_STREAM_SETUP_INPROGRESS); |
@@ -1202,7 +1201,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) | |||
1202 | } | 1201 | } |
1203 | /* Minimum number of AMSDU */ | 1202 | /* Minimum number of AMSDU */ |
1204 | #define MIN_NUM_AMSDU 2 | 1203 | #define MIN_NUM_AMSDU 2 |
1205 | if (mwifiex_is_amsdu_allowed(priv, ptr, tid) && | 1204 | if (mwifiex_is_amsdu_allowed(priv, tid) && |
1206 | (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= | 1205 | (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= |
1207 | MIN_NUM_AMSDU)) | 1206 | MIN_NUM_AMSDU)) |
1208 | mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, | 1207 | mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, |
@@ -1232,6 +1231,4 @@ mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) | |||
1232 | if (mwifiex_dequeue_tx_packet(adapter)) | 1231 | if (mwifiex_dequeue_tx_packet(adapter)) |
1233 | break; | 1232 | break; |
1234 | } while (true); | 1233 | } while (true); |
1235 | |||
1236 | return; | ||
1237 | } | 1234 | } |
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index 241f1b0b77f9..fcea1f68792f 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h | |||
@@ -35,8 +35,7 @@ enum ieee_types_wmm_ecw_bitmasks { | |||
35 | * This function retrieves the TID of the given RA list. | 35 | * This function retrieves the TID of the given RA list. |
36 | */ | 36 | */ |
37 | static inline int | 37 | static inline int |
38 | mwifiex_get_tid(struct mwifiex_adapter *adapter, | 38 | mwifiex_get_tid(struct mwifiex_ra_list_tbl *ptr) |
39 | struct mwifiex_ra_list_tbl *ptr) | ||
40 | { | 39 | { |
41 | struct sk_buff *skb; | 40 | struct sk_buff *skb; |
42 | 41 | ||
@@ -52,7 +51,7 @@ mwifiex_get_tid(struct mwifiex_adapter *adapter, | |||
52 | * This function gets the length of a list. | 51 | * This function gets the length of a list. |
53 | */ | 52 | */ |
54 | static inline int | 53 | static inline int |
55 | mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) | 54 | mwifiex_wmm_list_len(struct list_head *head) |
56 | { | 55 | { |
57 | struct list_head *pos; | 56 | struct list_head *pos; |
58 | int count = 0; | 57 | int count = 0; |
@@ -67,8 +66,7 @@ mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) | |||
67 | * This function checks if a RA list is empty or not. | 66 | * This function checks if a RA list is empty or not. |
68 | */ | 67 | */ |
69 | static inline u8 | 68 | static inline u8 |
70 | mwifiex_wmm_is_ra_list_empty(struct mwifiex_adapter *adapter, | 69 | mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) |
71 | struct list_head *ra_list_hhead) | ||
72 | { | 70 | { |
73 | struct mwifiex_ra_list_tbl *ra_list; | 71 | struct mwifiex_ra_list_tbl *ra_list; |
74 | int is_list_empty; | 72 | int is_list_empty; |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 8913180a7bd3..28ebaec80be6 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -289,10 +289,17 @@ struct mwl8k_vif { | |||
289 | #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) | 289 | #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) |
290 | #define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8)) | 290 | #define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8)) |
291 | 291 | ||
292 | struct tx_traffic_info { | ||
293 | u32 start_time; | ||
294 | u32 pkts; | ||
295 | }; | ||
296 | |||
297 | #define MWL8K_MAX_TID 8 | ||
292 | struct mwl8k_sta { | 298 | struct mwl8k_sta { |
293 | /* Index into station database. Returned by UPDATE_STADB. */ | 299 | /* Index into station database. Returned by UPDATE_STADB. */ |
294 | u8 peer_id; | 300 | u8 peer_id; |
295 | u8 is_ampdu_allowed; | 301 | u8 is_ampdu_allowed; |
302 | struct tx_traffic_info tx_stats[MWL8K_MAX_TID]; | ||
296 | }; | 303 | }; |
297 | #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) | 304 | #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) |
298 | 305 | ||
@@ -701,7 +708,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw) | |||
701 | "helper image\n", pci_name(priv->pdev)); | 708 | "helper image\n", pci_name(priv->pdev)); |
702 | return rc; | 709 | return rc; |
703 | } | 710 | } |
704 | msleep(5); | 711 | msleep(20); |
705 | 712 | ||
706 | rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); | 713 | rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); |
707 | } else { | 714 | } else { |
@@ -823,8 +830,8 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb) | |||
823 | /* | 830 | /* |
824 | * Make sure the packet header is in the DMA header format (4-address | 831 | * Make sure the packet header is in the DMA header format (4-address |
825 | * without QoS), the necessary crypto padding between the header and the | 832 | * without QoS), the necessary crypto padding between the header and the |
826 | * payload has already been provided by mac80211, but it doesn't add tail | 833 | * payload has already been provided by mac80211, but it doesn't add |
827 | * padding when HW crypto is enabled. | 834 | * tail padding when HW crypto is enabled. |
828 | * | 835 | * |
829 | * We have the following trailer padding requirements: | 836 | * We have the following trailer padding requirements: |
830 | * - WEP: 4 trailer bytes (ICV) | 837 | * - WEP: 4 trailer bytes (ICV) |
@@ -1487,9 +1494,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) | |||
1487 | 1494 | ||
1488 | if (timeout) { | 1495 | if (timeout) { |
1489 | WARN_ON(priv->pending_tx_pkts); | 1496 | WARN_ON(priv->pending_tx_pkts); |
1490 | if (retry) { | 1497 | if (retry) |
1491 | wiphy_notice(hw->wiphy, "tx rings drained\n"); | 1498 | wiphy_notice(hw->wiphy, "tx rings drained\n"); |
1492 | } | ||
1493 | break; | 1499 | break; |
1494 | } | 1500 | } |
1495 | 1501 | ||
@@ -1649,8 +1655,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) | |||
1649 | /* Rate control is happening in the firmware. | 1655 | /* Rate control is happening in the firmware. |
1650 | * Ensure no tx rate is being reported. | 1656 | * Ensure no tx rate is being reported. |
1651 | */ | 1657 | */ |
1652 | info->status.rates[0].idx = -1; | 1658 | info->status.rates[0].idx = -1; |
1653 | info->status.rates[0].count = 1; | 1659 | info->status.rates[0].count = 1; |
1654 | 1660 | ||
1655 | if (MWL8K_TXD_SUCCESS(status)) | 1661 | if (MWL8K_TXD_SUCCESS(status)) |
1656 | info->flags |= IEEE80211_TX_STAT_ACK; | 1662 | info->flags |= IEEE80211_TX_STAT_ACK; |
@@ -1688,7 +1694,7 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index) | |||
1688 | } | 1694 | } |
1689 | 1695 | ||
1690 | /* caller must hold priv->stream_lock when calling the stream functions */ | 1696 | /* caller must hold priv->stream_lock when calling the stream functions */ |
1691 | struct mwl8k_ampdu_stream * | 1697 | static struct mwl8k_ampdu_stream * |
1692 | mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) | 1698 | mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) |
1693 | { | 1699 | { |
1694 | struct mwl8k_ampdu_stream *stream; | 1700 | struct mwl8k_ampdu_stream *stream; |
@@ -1755,6 +1761,41 @@ mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid) | |||
1755 | return NULL; | 1761 | return NULL; |
1756 | } | 1762 | } |
1757 | 1763 | ||
1764 | #define MWL8K_AMPDU_PACKET_THRESHOLD 64 | ||
1765 | static inline bool mwl8k_ampdu_allowed(struct ieee80211_sta *sta, u8 tid) | ||
1766 | { | ||
1767 | struct mwl8k_sta *sta_info = MWL8K_STA(sta); | ||
1768 | struct tx_traffic_info *tx_stats; | ||
1769 | |||
1770 | BUG_ON(tid >= MWL8K_MAX_TID); | ||
1771 | tx_stats = &sta_info->tx_stats[tid]; | ||
1772 | |||
1773 | return sta_info->is_ampdu_allowed && | ||
1774 | tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD; | ||
1775 | } | ||
1776 | |||
1777 | static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid) | ||
1778 | { | ||
1779 | struct mwl8k_sta *sta_info = MWL8K_STA(sta); | ||
1780 | struct tx_traffic_info *tx_stats; | ||
1781 | |||
1782 | BUG_ON(tid >= MWL8K_MAX_TID); | ||
1783 | tx_stats = &sta_info->tx_stats[tid]; | ||
1784 | |||
1785 | if (tx_stats->start_time == 0) | ||
1786 | tx_stats->start_time = jiffies; | ||
1787 | |||
1788 | /* reset the packet count after each second elapses. If the number of | ||
1789 | * packets ever exceeds the ampdu_min_traffic threshold, we will allow | ||
1790 | * an ampdu stream to be started. | ||
1791 | */ | ||
1792 | if (jiffies - tx_stats->start_time > HZ) { | ||
1793 | tx_stats->pkts = 0; | ||
1794 | tx_stats->start_time = 0; | ||
1795 | } else | ||
1796 | tx_stats->pkts++; | ||
1797 | } | ||
1798 | |||
1758 | static void | 1799 | static void |
1759 | mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | 1800 | mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) |
1760 | { | 1801 | { |
@@ -1841,6 +1882,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
1841 | skb->protocol != cpu_to_be16(ETH_P_PAE) && | 1882 | skb->protocol != cpu_to_be16(ETH_P_PAE) && |
1842 | sta->ht_cap.ht_supported && priv->ap_fw) { | 1883 | sta->ht_cap.ht_supported && priv->ap_fw) { |
1843 | tid = qos & 0xf; | 1884 | tid = qos & 0xf; |
1885 | mwl8k_tx_count_packet(sta, tid); | ||
1844 | spin_lock(&priv->stream_lock); | 1886 | spin_lock(&priv->stream_lock); |
1845 | stream = mwl8k_lookup_stream(hw, sta->addr, tid); | 1887 | stream = mwl8k_lookup_stream(hw, sta->addr, tid); |
1846 | if (stream != NULL) { | 1888 | if (stream != NULL) { |
@@ -1881,7 +1923,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
1881 | * prevents sequence number mismatch at the recepient | 1923 | * prevents sequence number mismatch at the recepient |
1882 | * as described above. | 1924 | * as described above. |
1883 | */ | 1925 | */ |
1884 | if (MWL8K_STA(sta)->is_ampdu_allowed) { | 1926 | if (mwl8k_ampdu_allowed(sta, tid)) { |
1885 | stream = mwl8k_add_stream(hw, sta, tid); | 1927 | stream = mwl8k_add_stream(hw, sta, tid); |
1886 | if (stream != NULL) | 1928 | if (stream != NULL) |
1887 | start_ba_session = true; | 1929 | start_ba_session = true; |
@@ -2657,7 +2699,7 @@ struct mwl8k_cmd_tx_power { | |||
2657 | __le16 bw; | 2699 | __le16 bw; |
2658 | __le16 sub_ch; | 2700 | __le16 sub_ch; |
2659 | __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; | 2701 | __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; |
2660 | } __attribute__((packed)); | 2702 | } __packed; |
2661 | 2703 | ||
2662 | static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, | 2704 | static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, |
2663 | struct ieee80211_conf *conf, | 2705 | struct ieee80211_conf *conf, |
@@ -3520,13 +3562,13 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, | |||
3520 | #define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00 | 3562 | #define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00 |
3521 | #define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01 | 3563 | #define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01 |
3522 | 3564 | ||
3523 | enum { | 3565 | enum ba_stream_action_type { |
3524 | MWL8K_BA_CREATE, | 3566 | MWL8K_BA_CREATE, |
3525 | MWL8K_BA_UPDATE, | 3567 | MWL8K_BA_UPDATE, |
3526 | MWL8K_BA_DESTROY, | 3568 | MWL8K_BA_DESTROY, |
3527 | MWL8K_BA_FLUSH, | 3569 | MWL8K_BA_FLUSH, |
3528 | MWL8K_BA_CHECK, | 3570 | MWL8K_BA_CHECK, |
3529 | } ba_stream_action_type; | 3571 | }; |
3530 | 3572 | ||
3531 | 3573 | ||
3532 | struct mwl8k_create_ba_stream { | 3574 | struct mwl8k_create_ba_stream { |
@@ -3780,7 +3822,7 @@ struct mwl8k_cmd_update_encryption { | |||
3780 | __u8 mac_addr[6]; | 3822 | __u8 mac_addr[6]; |
3781 | __u8 encr_type; | 3823 | __u8 encr_type; |
3782 | 3824 | ||
3783 | } __attribute__((packed)); | 3825 | } __packed; |
3784 | 3826 | ||
3785 | struct mwl8k_cmd_set_key { | 3827 | struct mwl8k_cmd_set_key { |
3786 | struct mwl8k_cmd_pkt header; | 3828 | struct mwl8k_cmd_pkt header; |
@@ -3800,7 +3842,7 @@ struct mwl8k_cmd_set_key { | |||
3800 | __le16 tkip_tsc_low; | 3842 | __le16 tkip_tsc_low; |
3801 | __le32 tkip_tsc_high; | 3843 | __le32 tkip_tsc_high; |
3802 | __u8 mac_addr[6]; | 3844 | __u8 mac_addr[6]; |
3803 | } __attribute__((packed)); | 3845 | } __packed; |
3804 | 3846 | ||
3805 | enum { | 3847 | enum { |
3806 | MWL8K_ENCR_ENABLE, | 3848 | MWL8K_ENCR_ENABLE, |
@@ -4285,6 +4327,8 @@ static int mwl8k_start(struct ieee80211_hw *hw) | |||
4285 | 4327 | ||
4286 | /* Enable interrupts */ | 4328 | /* Enable interrupts */ |
4287 | iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); | 4329 | iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); |
4330 | iowrite32(MWL8K_A2H_EVENTS, | ||
4331 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | ||
4288 | 4332 | ||
4289 | rc = mwl8k_fw_lock(hw); | 4333 | rc = mwl8k_fw_lock(hw); |
4290 | if (!rc) { | 4334 | if (!rc) { |
@@ -4502,7 +4546,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
4502 | struct ieee80211_bss_conf *info, u32 changed) | 4546 | struct ieee80211_bss_conf *info, u32 changed) |
4503 | { | 4547 | { |
4504 | struct mwl8k_priv *priv = hw->priv; | 4548 | struct mwl8k_priv *priv = hw->priv; |
4505 | u32 ap_legacy_rates; | 4549 | u32 ap_legacy_rates = 0; |
4506 | u8 ap_mcs_rates[16]; | 4550 | u8 ap_mcs_rates[16]; |
4507 | int rc; | 4551 | int rc; |
4508 | 4552 | ||
@@ -5283,7 +5327,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) | |||
5283 | iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY| | 5327 | iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY| |
5284 | MWL8K_A2H_INT_BA_WATCHDOG, | 5328 | MWL8K_A2H_INT_BA_WATCHDOG, |
5285 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); | 5329 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); |
5286 | iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | 5330 | iowrite32(MWL8K_A2H_INT_OPC_DONE, |
5331 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | ||
5287 | 5332 | ||
5288 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | 5333 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, |
5289 | IRQF_SHARED, MWL8K_NAME, hw); | 5334 | IRQF_SHARED, MWL8K_NAME, hw); |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6ba31a0e8f78..d2f5c87305a4 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -710,6 +710,16 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
710 | { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 710 | { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, |
711 | { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, | 711 | { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, |
712 | { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, | 712 | { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, |
713 | /* Alpha Networks */ | ||
714 | { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
715 | { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
716 | { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
717 | { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
718 | { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
719 | { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
720 | { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
721 | { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
722 | { USB_DEVICE(0x14b2, 0x3c2c), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
713 | /* Amit */ | 723 | /* Amit */ |
714 | { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, | 724 | { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, |
715 | /* Askey */ | 725 | /* Askey */ |
@@ -736,15 +746,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
736 | /* Buffalo */ | 746 | /* Buffalo */ |
737 | { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, | 747 | { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, |
738 | { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 748 | { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) }, |
739 | /* Conceptronic */ | 749 | { USB_DEVICE(0x0411, 0x01a2), USB_DEVICE_DATA(&rt2800usb_ops) }, |
740 | { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
741 | { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
742 | { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
743 | { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
744 | { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
745 | { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
746 | { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
747 | { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
748 | /* Corega */ | 750 | /* Corega */ |
749 | { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 751 | { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, |
750 | { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 752 | { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -776,6 +778,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
776 | { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, | 778 | { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, |
777 | { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, | 779 | { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, |
778 | { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, | 780 | { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, |
781 | /* Gemtek */ | ||
782 | { USB_DEVICE(0x15a9, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
779 | /* Gigabyte */ | 783 | /* Gigabyte */ |
780 | { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 784 | { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, |
781 | { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, | 785 | { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -792,6 +796,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
792 | { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, | 796 | { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, |
793 | { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, | 797 | { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, |
794 | /* Linksys */ | 798 | /* Linksys */ |
799 | { USB_DEVICE(0x13b1, 0x0031), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
795 | { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 800 | { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, |
796 | { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, | 801 | { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, |
797 | /* Logitec */ | 802 | /* Logitec */ |
@@ -870,8 +875,9 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
870 | { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, | 875 | { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, |
871 | /* Sweex */ | 876 | /* Sweex */ |
872 | { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) }, | 877 | { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) }, |
873 | /* U-Media*/ | 878 | /* U-Media */ |
874 | { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) }, | 879 | { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) }, |
880 | { USB_DEVICE(0x157e, 0x3013), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
875 | /* ZCOM */ | 881 | /* ZCOM */ |
876 | { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) }, | 882 | { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) }, |
877 | { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) }, | 883 | { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -883,6 +889,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
883 | /* Zyxel */ | 889 | /* Zyxel */ |
884 | { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, | 890 | { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, |
885 | { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) }, | 891 | { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) }, |
892 | { USB_DEVICE(0x0586, 0x341e), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
886 | #ifdef CONFIG_RT2800USB_RT33XX | 893 | #ifdef CONFIG_RT2800USB_RT33XX |
887 | /* Ralink */ | 894 | /* Ralink */ |
888 | { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, | 895 | { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -901,6 +908,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
901 | { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) }, | 908 | { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) }, |
902 | /* I-O DATA */ | 909 | /* I-O DATA */ |
903 | { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, | 910 | { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, |
911 | /* Linksys */ | ||
912 | { USB_DEVICE(0x13b1, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
904 | /* Ralink */ | 913 | /* Ralink */ |
905 | { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, | 914 | { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, |
906 | /* Sitecom */ | 915 | /* Sitecom */ |
@@ -915,6 +924,9 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
915 | * Unclear what kind of devices these are (they aren't supported by the | 924 | * Unclear what kind of devices these are (they aren't supported by the |
916 | * vendor linux driver). | 925 | * vendor linux driver). |
917 | */ | 926 | */ |
927 | /* Alpha Networks */ | ||
928 | { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
929 | { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
918 | /* Amigo */ | 930 | /* Amigo */ |
919 | { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, | 931 | { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, |
920 | { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, | 932 | { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -933,9 +945,6 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
933 | { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) }, | 945 | { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) }, |
934 | { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) }, | 946 | { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) }, |
935 | { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) }, | 947 | { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) }, |
936 | /* Conceptronic */ | ||
937 | { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
938 | { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
939 | /* Corega */ | 948 | /* Corega */ |
940 | { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, | 949 | { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, |
941 | { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, | 950 | { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index dd5318ed7872..9477785f1168 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -251,14 +251,16 @@ void rtl_init_rfkill(struct ieee80211_hw *hw) | |||
251 | bool blocked; | 251 | bool blocked; |
252 | u8 valid = 0; | 252 | u8 valid = 0; |
253 | 253 | ||
254 | radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); | 254 | /*set init state to on */ |
255 | rtlpriv->rfkill.rfkill_state = 1; | ||
256 | wiphy_rfkill_set_hw_state(hw->wiphy, 0); | ||
255 | 257 | ||
256 | /*set init state to that of switch */ | 258 | radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); |
257 | rtlpriv->rfkill.rfkill_state = radio_state; | ||
258 | printk(KERN_INFO "rtlwifi: wireless switch is %s\n", | ||
259 | rtlpriv->rfkill.rfkill_state ? "on" : "off"); | ||
260 | 259 | ||
261 | if (valid) { | 260 | if (valid) { |
261 | printk(KERN_INFO "rtlwifi: wireless switch is %s\n", | ||
262 | rtlpriv->rfkill.rfkill_state ? "on" : "off"); | ||
263 | |||
262 | rtlpriv->rfkill.rfkill_state = radio_state; | 264 | rtlpriv->rfkill.rfkill_state = radio_state; |
263 | 265 | ||
264 | blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; | 266 | blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index efded435d596..59a150ce3064 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -1785,7 +1785,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev) | |||
1785 | 1785 | ||
1786 | rtl_pci_deinit(hw); | 1786 | rtl_pci_deinit(hw); |
1787 | rtl_deinit_core(hw); | 1787 | rtl_deinit_core(hw); |
1788 | rtlpriv->cfg->ops->deinit_sw_leds(hw); | 1788 | if (rtlpriv->cfg->ops->deinit_sw_leds) |
1789 | rtlpriv->cfg->ops->deinit_sw_leds(hw); | ||
1789 | _rtl_pci_io_handler_release(hw); | 1790 | _rtl_pci_io_handler_release(hw); |
1790 | rtlpriv->cfg->ops->deinit_sw_vars(hw); | 1791 | rtlpriv->cfg->ops->deinit_sw_vars(hw); |
1791 | 1792 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index bb023274414c..c228b9ee3711 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
@@ -634,7 +634,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | |||
634 | u8 thermalvalue, delta, delta_lck, delta_iqk; | 634 | u8 thermalvalue, delta, delta_lck, delta_iqk; |
635 | long ele_a, ele_d, temp_cck, val_x, value32; | 635 | long ele_a, ele_d, temp_cck, val_x, value32; |
636 | long val_y, ele_c; | 636 | long val_y, ele_c; |
637 | u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; | 637 | u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; |
638 | int i; | 638 | int i; |
639 | bool is2t = IS_92C_SERIAL(rtlhal->version); | 639 | bool is2t = IS_92C_SERIAL(rtlhal->version); |
640 | u8 txpwr_level[2] = {0, 0}; | 640 | u8 txpwr_level[2] = {0, 0}; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index f107660f545d..bc9d24134ac4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | |||
@@ -293,7 +293,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, | |||
293 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 293 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
294 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 294 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
295 | u8 boxnum; | 295 | u8 boxnum; |
296 | u16 box_reg, box_extreg; | 296 | u16 box_reg = 0, box_extreg = 0; |
297 | u8 u1b_tmp; | 297 | u8 u1b_tmp; |
298 | bool isfw_read = false; | 298 | bool isfw_read = false; |
299 | bool bwrite_sucess = false; | 299 | bool bwrite_sucess = false; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 7b1da8d7508f..d21b934b5c33 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c | |||
@@ -32,6 +32,14 @@ | |||
32 | #include "reg.h" | 32 | #include "reg.h" |
33 | #include "led.h" | 33 | #include "led.h" |
34 | 34 | ||
35 | static void _rtl92ce_init_led(struct ieee80211_hw *hw, | ||
36 | struct rtl_led *pled, enum rtl_led_pin ledpin) | ||
37 | { | ||
38 | pled->hw = hw; | ||
39 | pled->ledpin = ledpin; | ||
40 | pled->ledon = false; | ||
41 | } | ||
42 | |||
35 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) | 43 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) |
36 | { | 44 | { |
37 | u8 ledcfg; | 45 | u8 ledcfg; |
@@ -97,10 +105,10 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | |||
97 | 105 | ||
98 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) | 106 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) |
99 | { | 107 | { |
100 | } | 108 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); |
101 | 109 | ||
102 | void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw) | 110 | _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); |
103 | { | 111 | _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); |
104 | } | 112 | } |
105 | 113 | ||
106 | void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, | 114 | void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h index 10da3018f4b7..94332b3af5b1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h | |||
@@ -31,7 +31,6 @@ | |||
31 | #define __RTL92CE_LED_H__ | 31 | #define __RTL92CE_LED_H__ |
32 | 32 | ||
33 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); | 33 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); |
34 | void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw); | ||
35 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); | 34 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); |
36 | void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); | 35 | void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); |
37 | void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); | 36 | void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 669b1168dbec..e301b12e281a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | |||
@@ -202,7 +202,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, | |||
202 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 202 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
203 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 203 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
204 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 204 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
205 | u8 i, chnlgroup, pwr_diff_limit[4]; | 205 | u8 i, chnlgroup = 0, pwr_diff_limit[4]; |
206 | u32 writeVal, customer_limit, rf; | 206 | u32 writeVal, customer_limit, rf; |
207 | 207 | ||
208 | for (rf = 0; rf < 2; rf++) { | 208 | for (rf = 0; rf < 2; rf++) { |
@@ -447,7 +447,7 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) | |||
447 | { | 447 | { |
448 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 448 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
449 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 449 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
450 | u32 u4_regvalue; | 450 | u32 u4_regvalue = 0; |
451 | u8 rfpath; | 451 | u8 rfpath; |
452 | bool rtstatus; | 452 | bool rtstatus; |
453 | struct bb_reg_def *pphyreg; | 453 | struct bb_reg_def *pphyreg; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index b1cc4d44f534..f4e2f3dcccae 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | |||
@@ -131,7 +131,6 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { | |||
131 | .enable_hw_sec = rtl92ce_enable_hw_security_config, | 131 | .enable_hw_sec = rtl92ce_enable_hw_security_config, |
132 | .set_key = rtl92ce_set_key, | 132 | .set_key = rtl92ce_set_key, |
133 | .init_sw_leds = rtl92ce_init_sw_leds, | 133 | .init_sw_leds = rtl92ce_init_sw_leds, |
134 | .deinit_sw_leds = rtl92ce_deinit_sw_leds, | ||
135 | .get_bbreg = rtl92c_phy_query_bb_reg, | 134 | .get_bbreg = rtl92c_phy_query_bb_reg, |
136 | .set_bbreg = rtl92c_phy_set_bb_reg, | 135 | .set_bbreg = rtl92c_phy_set_bb_reg, |
137 | .get_rfreg = rtl92ce_phy_query_rf_reg, | 136 | .get_rfreg = rtl92ce_phy_query_rf_reg, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 9444e76838cf..e43be2547827 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
@@ -921,7 +921,7 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw, | |||
921 | u8 out_ep_num, | 921 | u8 out_ep_num, |
922 | u8 queue_sel) | 922 | u8 queue_sel) |
923 | { | 923 | { |
924 | u8 hq_sele; | 924 | u8 hq_sele = 0; |
925 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 925 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
926 | 926 | ||
927 | switch (out_ep_num) { | 927 | switch (out_ep_num) { |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 16eea7229e99..be8df57b789d 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -410,6 +410,16 @@ | |||
410 | * notification. This event is used to indicate that an unprotected | 410 | * notification. This event is used to indicate that an unprotected |
411 | * disassociation frame was dropped when MFP is in use. | 411 | * disassociation frame was dropped when MFP is in use. |
412 | * | 412 | * |
413 | * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a | ||
414 | * beacon or probe response from a compatible mesh peer. This is only | ||
415 | * sent while no station information (sta_info) exists for the new peer | ||
416 | * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On | ||
417 | * reception of this notification, userspace may decide to create a new | ||
418 | * station (@NL80211_CMD_NEW_STATION). To stop this notification from | ||
419 | * reoccurring, the userspace authentication daemon may want to create the | ||
420 | * new station with the AUTHENTICATED flag unset and maybe change it later | ||
421 | * depending on the authentication result. | ||
422 | * | ||
413 | * @NL80211_CMD_MAX: highest used command number | 423 | * @NL80211_CMD_MAX: highest used command number |
414 | * @__NL80211_CMD_AFTER_LAST: internal use | 424 | * @__NL80211_CMD_AFTER_LAST: internal use |
415 | */ | 425 | */ |
@@ -522,6 +532,8 @@ enum nl80211_commands { | |||
522 | NL80211_CMD_UNPROT_DEAUTHENTICATE, | 532 | NL80211_CMD_UNPROT_DEAUTHENTICATE, |
523 | NL80211_CMD_UNPROT_DISASSOCIATE, | 533 | NL80211_CMD_UNPROT_DISASSOCIATE, |
524 | 534 | ||
535 | NL80211_CMD_NEW_PEER_CANDIDATE, | ||
536 | |||
525 | /* add new commands above here */ | 537 | /* add new commands above here */ |
526 | 538 | ||
527 | /* used to define NL80211_CMD_MAX below */ | 539 | /* used to define NL80211_CMD_MAX below */ |
@@ -545,6 +557,7 @@ enum nl80211_commands { | |||
545 | /* source-level API compatibility */ | 557 | /* source-level API compatibility */ |
546 | #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG | 558 | #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG |
547 | #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG | 559 | #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG |
560 | #define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE | ||
548 | 561 | ||
549 | /** | 562 | /** |
550 | * enum nl80211_attrs - nl80211 netlink attributes | 563 | * enum nl80211_attrs - nl80211 netlink attributes |
@@ -886,6 +899,9 @@ enum nl80211_commands { | |||
886 | * changed once the mesh is active. | 899 | * changed once the mesh is active. |
887 | * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute | 900 | * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute |
888 | * containing attributes from &enum nl80211_meshconf_params. | 901 | * containing attributes from &enum nl80211_meshconf_params. |
902 | * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver | ||
903 | * allows auth frames in a mesh to be passed to userspace for processing via | ||
904 | * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. | ||
889 | * | 905 | * |
890 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 906 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
891 | * @__NL80211_ATTR_AFTER_LAST: internal use | 907 | * @__NL80211_ATTR_AFTER_LAST: internal use |
@@ -1074,6 +1090,8 @@ enum nl80211_attrs { | |||
1074 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, | 1090 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, |
1075 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, | 1091 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, |
1076 | 1092 | ||
1093 | NL80211_ATTR_SUPPORT_MESH_AUTH, | ||
1094 | |||
1077 | /* add attributes here, update the policy in nl80211.c */ | 1095 | /* add attributes here, update the policy in nl80211.c */ |
1078 | 1096 | ||
1079 | __NL80211_ATTR_AFTER_LAST, | 1097 | __NL80211_ATTR_AFTER_LAST, |
@@ -1168,6 +1186,7 @@ enum nl80211_iftype { | |||
1168 | * with short barker preamble | 1186 | * with short barker preamble |
1169 | * @NL80211_STA_FLAG_WME: station is WME/QoS capable | 1187 | * @NL80211_STA_FLAG_WME: station is WME/QoS capable |
1170 | * @NL80211_STA_FLAG_MFP: station uses management frame protection | 1188 | * @NL80211_STA_FLAG_MFP: station uses management frame protection |
1189 | * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated | ||
1171 | * @NL80211_STA_FLAG_MAX: highest station flag number currently defined | 1190 | * @NL80211_STA_FLAG_MAX: highest station flag number currently defined |
1172 | * @__NL80211_STA_FLAG_AFTER_LAST: internal use | 1191 | * @__NL80211_STA_FLAG_AFTER_LAST: internal use |
1173 | */ | 1192 | */ |
@@ -1177,6 +1196,7 @@ enum nl80211_sta_flags { | |||
1177 | NL80211_STA_FLAG_SHORT_PREAMBLE, | 1196 | NL80211_STA_FLAG_SHORT_PREAMBLE, |
1178 | NL80211_STA_FLAG_WME, | 1197 | NL80211_STA_FLAG_WME, |
1179 | NL80211_STA_FLAG_MFP, | 1198 | NL80211_STA_FLAG_MFP, |
1199 | NL80211_STA_FLAG_AUTHENTICATED, | ||
1180 | 1200 | ||
1181 | /* keep last */ | 1201 | /* keep last */ |
1182 | __NL80211_STA_FLAG_AFTER_LAST, | 1202 | __NL80211_STA_FLAG_AFTER_LAST, |
@@ -1277,6 +1297,7 @@ enum nl80211_sta_bss_param { | |||
1277 | * attribute, like NL80211_STA_INFO_TX_BITRATE. | 1297 | * attribute, like NL80211_STA_INFO_TX_BITRATE. |
1278 | * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute | 1298 | * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute |
1279 | * containing info as possible, see &enum nl80211_sta_bss_param | 1299 | * containing info as possible, see &enum nl80211_sta_bss_param |
1300 | * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected | ||
1280 | * @__NL80211_STA_INFO_AFTER_LAST: internal | 1301 | * @__NL80211_STA_INFO_AFTER_LAST: internal |
1281 | * @NL80211_STA_INFO_MAX: highest possible station info attribute | 1302 | * @NL80211_STA_INFO_MAX: highest possible station info attribute |
1282 | */ | 1303 | */ |
@@ -1297,6 +1318,7 @@ enum nl80211_sta_info { | |||
1297 | NL80211_STA_INFO_SIGNAL_AVG, | 1318 | NL80211_STA_INFO_SIGNAL_AVG, |
1298 | NL80211_STA_INFO_RX_BITRATE, | 1319 | NL80211_STA_INFO_RX_BITRATE, |
1299 | NL80211_STA_INFO_BSS_PARAM, | 1320 | NL80211_STA_INFO_BSS_PARAM, |
1321 | NL80211_STA_INFO_CONNECTED_TIME, | ||
1300 | 1322 | ||
1301 | /* keep last */ | 1323 | /* keep last */ |
1302 | __NL80211_STA_INFO_AFTER_LAST, | 1324 | __NL80211_STA_INFO_AFTER_LAST, |
@@ -1719,9 +1741,12 @@ enum nl80211_meshconf_params { | |||
1719 | * vendor specific path metric or disable it to use the default Airtime | 1741 | * vendor specific path metric or disable it to use the default Airtime |
1720 | * metric. | 1742 | * metric. |
1721 | * | 1743 | * |
1722 | * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information | 1744 | * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a |
1723 | * element that vendors will use to identify the path selection methods and | 1745 | * robust security network ie, or a vendor specific information element that |
1724 | * metrics in use. | 1746 | * vendors will use to identify the path selection methods and metrics in use. |
1747 | * | ||
1748 | * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication | ||
1749 | * daemon will be authenticating mesh candidates. | ||
1725 | * | 1750 | * |
1726 | * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number | 1751 | * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number |
1727 | * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use | 1752 | * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use |
@@ -1730,7 +1755,8 @@ enum nl80211_mesh_setup_params { | |||
1730 | __NL80211_MESH_SETUP_INVALID, | 1755 | __NL80211_MESH_SETUP_INVALID, |
1731 | NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, | 1756 | NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, |
1732 | NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, | 1757 | NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, |
1733 | NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE, | 1758 | NL80211_MESH_SETUP_IE, |
1759 | NL80211_MESH_SETUP_USERSPACE_AUTH, | ||
1734 | 1760 | ||
1735 | /* keep last */ | 1761 | /* keep last */ |
1736 | __NL80211_MESH_SETUP_ATTR_AFTER_LAST, | 1762 | __NL80211_MESH_SETUP_ATTR_AFTER_LAST, |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ba7384acf4e0..d30eada7c6cd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -423,6 +423,7 @@ struct station_parameters { | |||
423 | * @STATION_INFO_SIGNAL_AVG: @signal_avg filled | 423 | * @STATION_INFO_SIGNAL_AVG: @signal_avg filled |
424 | * @STATION_INFO_RX_BITRATE: @rxrate fields are filled | 424 | * @STATION_INFO_RX_BITRATE: @rxrate fields are filled |
425 | * @STATION_INFO_BSS_PARAM: @bss_param filled | 425 | * @STATION_INFO_BSS_PARAM: @bss_param filled |
426 | * @STATION_INFO_CONNECTED_TIME: @connected_time filled | ||
426 | */ | 427 | */ |
427 | enum station_info_flags { | 428 | enum station_info_flags { |
428 | STATION_INFO_INACTIVE_TIME = 1<<0, | 429 | STATION_INFO_INACTIVE_TIME = 1<<0, |
@@ -441,6 +442,7 @@ enum station_info_flags { | |||
441 | STATION_INFO_SIGNAL_AVG = 1<<13, | 442 | STATION_INFO_SIGNAL_AVG = 1<<13, |
442 | STATION_INFO_RX_BITRATE = 1<<14, | 443 | STATION_INFO_RX_BITRATE = 1<<14, |
443 | STATION_INFO_BSS_PARAM = 1<<15, | 444 | STATION_INFO_BSS_PARAM = 1<<15, |
445 | STATION_INFO_CONNECTED_TIME = 1<<16 | ||
444 | }; | 446 | }; |
445 | 447 | ||
446 | /** | 448 | /** |
@@ -511,6 +513,7 @@ struct sta_bss_parameters { | |||
511 | * Station information filled by driver for get_station() and dump_station. | 513 | * Station information filled by driver for get_station() and dump_station. |
512 | * | 514 | * |
513 | * @filled: bitflag of flags from &enum station_info_flags | 515 | * @filled: bitflag of flags from &enum station_info_flags |
516 | * @connected_time: time(in secs) since a station is last connected | ||
514 | * @inactive_time: time since last station activity (tx/rx) in milliseconds | 517 | * @inactive_time: time since last station activity (tx/rx) in milliseconds |
515 | * @rx_bytes: bytes received from this station | 518 | * @rx_bytes: bytes received from this station |
516 | * @tx_bytes: bytes transmitted to this station | 519 | * @tx_bytes: bytes transmitted to this station |
@@ -533,6 +536,7 @@ struct sta_bss_parameters { | |||
533 | */ | 536 | */ |
534 | struct station_info { | 537 | struct station_info { |
535 | u32 filled; | 538 | u32 filled; |
539 | u32 connected_time; | ||
536 | u32 inactive_time; | 540 | u32 inactive_time; |
537 | u32 rx_bytes; | 541 | u32 rx_bytes; |
538 | u32 tx_bytes; | 542 | u32 tx_bytes; |
@@ -689,8 +693,9 @@ struct mesh_config { | |||
689 | * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes | 693 | * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes |
690 | * @path_sel_proto: which path selection protocol to use | 694 | * @path_sel_proto: which path selection protocol to use |
691 | * @path_metric: which metric to use | 695 | * @path_metric: which metric to use |
692 | * @vendor_ie: vendor information elements (optional) | 696 | * @ie: vendor information elements (optional) |
693 | * @vendor_ie_len: length of vendor information elements | 697 | * @ie_len: length of vendor information elements |
698 | * @is_secure: or not | ||
694 | * | 699 | * |
695 | * These parameters are fixed when the mesh is created. | 700 | * These parameters are fixed when the mesh is created. |
696 | */ | 701 | */ |
@@ -699,8 +704,9 @@ struct mesh_setup { | |||
699 | u8 mesh_id_len; | 704 | u8 mesh_id_len; |
700 | u8 path_sel_proto; | 705 | u8 path_sel_proto; |
701 | u8 path_metric; | 706 | u8 path_metric; |
702 | const u8 *vendor_ie; | 707 | const u8 *ie; |
703 | u8 vendor_ie_len; | 708 | u8 ie_len; |
709 | bool is_secure; | ||
704 | }; | 710 | }; |
705 | 711 | ||
706 | /** | 712 | /** |
@@ -1451,6 +1457,8 @@ struct cfg80211_ops { | |||
1451 | * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. | 1457 | * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. |
1452 | * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate | 1458 | * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate |
1453 | * unicast and multicast TX keys. | 1459 | * unicast and multicast TX keys. |
1460 | * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing | ||
1461 | * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. | ||
1454 | */ | 1462 | */ |
1455 | enum wiphy_flags { | 1463 | enum wiphy_flags { |
1456 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), | 1464 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), |
@@ -1463,6 +1471,7 @@ enum wiphy_flags { | |||
1463 | WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), | 1471 | WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), |
1464 | WIPHY_FLAG_IBSS_RSN = BIT(8), | 1472 | WIPHY_FLAG_IBSS_RSN = BIT(8), |
1465 | WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9), | 1473 | WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9), |
1474 | WIPHY_FLAG_MESH_AUTH = BIT(10), | ||
1466 | }; | 1475 | }; |
1467 | 1476 | ||
1468 | struct mac_address { | 1477 | struct mac_address { |
@@ -2484,6 +2493,22 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, | |||
2484 | void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); | 2493 | void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); |
2485 | 2494 | ||
2486 | /** | 2495 | /** |
2496 | * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate | ||
2497 | * | ||
2498 | * @dev: network device | ||
2499 | * @macaddr: the MAC address of the new candidate | ||
2500 | * @ie: information elements advertised by the peer candidate | ||
2501 | * @ie_len: lenght of the information elements buffer | ||
2502 | * @gfp: allocation flags | ||
2503 | * | ||
2504 | * This function notifies cfg80211 that the mesh peer candidate has been | ||
2505 | * detected, most likely via a beacon or, less likely, via a probe response. | ||
2506 | * cfg80211 then sends a notification to userspace. | ||
2507 | */ | ||
2508 | void cfg80211_notify_new_peer_candidate(struct net_device *dev, | ||
2509 | const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp); | ||
2510 | |||
2511 | /** | ||
2487 | * DOC: RFkill integration | 2512 | * DOC: RFkill integration |
2488 | * | 2513 | * |
2489 | * RFkill integration in cfg80211 is almost invisible to drivers, | 2514 | * RFkill integration in cfg80211 is almost invisible to drivers, |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 965f1b16e53a..361bc5d85b1a 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1819,6 +1819,9 @@ enum ieee80211_ampdu_mlme_action { | |||
1819 | * @set_ringparam: Set tx and rx ring sizes. | 1819 | * @set_ringparam: Set tx and rx ring sizes. |
1820 | * | 1820 | * |
1821 | * @get_ringparam: Get tx and rx ring current and maximum sizes. | 1821 | * @get_ringparam: Get tx and rx ring current and maximum sizes. |
1822 | * | ||
1823 | * @tx_frames_pending: Check if there is any pending frame in the hardware | ||
1824 | * queues before entering power save. | ||
1822 | */ | 1825 | */ |
1823 | struct ieee80211_ops { | 1826 | struct ieee80211_ops { |
1824 | void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); | 1827 | void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); |
@@ -1906,6 +1909,7 @@ struct ieee80211_ops { | |||
1906 | int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); | 1909 | int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); |
1907 | void (*get_ringparam)(struct ieee80211_hw *hw, | 1910 | void (*get_ringparam)(struct ieee80211_hw *hw, |
1908 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); | 1911 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); |
1912 | bool (*tx_frames_pending)(struct ieee80211_hw *hw); | ||
1909 | }; | 1913 | }; |
1910 | 1914 | ||
1911 | /** | 1915 | /** |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bf5d28da46e6..a6d191f2a0fe 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -330,6 +330,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in | |||
330 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | 330 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) |
331 | { | 331 | { |
332 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 332 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
333 | struct timespec uptime; | ||
333 | 334 | ||
334 | sinfo->generation = sdata->local->sta_generation; | 335 | sinfo->generation = sdata->local->sta_generation; |
335 | 336 | ||
@@ -343,7 +344,11 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
343 | STATION_INFO_TX_BITRATE | | 344 | STATION_INFO_TX_BITRATE | |
344 | STATION_INFO_RX_BITRATE | | 345 | STATION_INFO_RX_BITRATE | |
345 | STATION_INFO_RX_DROP_MISC | | 346 | STATION_INFO_RX_DROP_MISC | |
346 | STATION_INFO_BSS_PARAM; | 347 | STATION_INFO_BSS_PARAM | |
348 | STATION_INFO_CONNECTED_TIME; | ||
349 | |||
350 | do_posix_clock_monotonic_gettime(&uptime); | ||
351 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; | ||
347 | 352 | ||
348 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); | 353 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); |
349 | sinfo->rx_bytes = sta->rx_bytes; | 354 | sinfo->rx_bytes = sta->rx_bytes; |
@@ -686,6 +691,12 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
686 | if (set & BIT(NL80211_STA_FLAG_MFP)) | 691 | if (set & BIT(NL80211_STA_FLAG_MFP)) |
687 | sta->flags |= WLAN_STA_MFP; | 692 | sta->flags |= WLAN_STA_MFP; |
688 | } | 693 | } |
694 | |||
695 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { | ||
696 | sta->flags &= ~WLAN_STA_AUTH; | ||
697 | if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) | ||
698 | sta->flags |= WLAN_STA_AUTH; | ||
699 | } | ||
689 | spin_unlock_irqrestore(&sta->flaglock, flags); | 700 | spin_unlock_irqrestore(&sta->flaglock, flags); |
690 | 701 | ||
691 | /* | 702 | /* |
@@ -1034,26 +1045,26 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, | |||
1034 | u8 *new_ie; | 1045 | u8 *new_ie; |
1035 | const u8 *old_ie; | 1046 | const u8 *old_ie; |
1036 | 1047 | ||
1037 | /* first allocate the new vendor information element */ | 1048 | /* allocate information elements */ |
1038 | new_ie = NULL; | 1049 | new_ie = NULL; |
1039 | old_ie = ifmsh->vendor_ie; | 1050 | old_ie = ifmsh->ie; |
1040 | 1051 | ||
1041 | ifmsh->vendor_ie_len = setup->vendor_ie_len; | 1052 | if (setup->ie_len) { |
1042 | if (setup->vendor_ie_len) { | 1053 | new_ie = kmemdup(setup->ie, setup->ie_len, |
1043 | new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len, | ||
1044 | GFP_KERNEL); | 1054 | GFP_KERNEL); |
1045 | if (!new_ie) | 1055 | if (!new_ie) |
1046 | return -ENOMEM; | 1056 | return -ENOMEM; |
1047 | } | 1057 | } |
1058 | ifmsh->ie_len = setup->ie_len; | ||
1059 | ifmsh->ie = new_ie; | ||
1060 | kfree(old_ie); | ||
1048 | 1061 | ||
1049 | /* now copy the rest of the setup parameters */ | 1062 | /* now copy the rest of the setup parameters */ |
1050 | ifmsh->mesh_id_len = setup->mesh_id_len; | 1063 | ifmsh->mesh_id_len = setup->mesh_id_len; |
1051 | memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); | 1064 | memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); |
1052 | ifmsh->mesh_pp_id = setup->path_sel_proto; | 1065 | ifmsh->mesh_pp_id = setup->path_sel_proto; |
1053 | ifmsh->mesh_pm_id = setup->path_metric; | 1066 | ifmsh->mesh_pm_id = setup->path_metric; |
1054 | ifmsh->vendor_ie = new_ie; | 1067 | ifmsh->is_secure = setup->is_secure; |
1055 | |||
1056 | kfree(old_ie); | ||
1057 | 1068 | ||
1058 | return 0; | 1069 | return 0; |
1059 | } | 1070 | } |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index c04a1396cf8d..c008232731eb 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -92,6 +92,31 @@ static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, | |||
92 | } | 92 | } |
93 | STA_OPS(inactive_ms); | 93 | STA_OPS(inactive_ms); |
94 | 94 | ||
95 | |||
96 | static ssize_t sta_connected_time_read(struct file *file, char __user *userbuf, | ||
97 | size_t count, loff_t *ppos) | ||
98 | { | ||
99 | struct sta_info *sta = file->private_data; | ||
100 | struct timespec uptime; | ||
101 | struct tm result; | ||
102 | long connected_time_secs; | ||
103 | char buf[100]; | ||
104 | int res; | ||
105 | do_posix_clock_monotonic_gettime(&uptime); | ||
106 | connected_time_secs = uptime.tv_sec - sta->last_connected; | ||
107 | time_to_tm(connected_time_secs, 0, &result); | ||
108 | result.tm_year -= 70; | ||
109 | result.tm_mday -= 1; | ||
110 | res = scnprintf(buf, sizeof(buf), | ||
111 | "years - %d\nmonths - %d\ndays - %d\nclock - %d:%d:%d\n\n", | ||
112 | result.tm_year, result.tm_mon, result.tm_mday, | ||
113 | result.tm_hour, result.tm_min, result.tm_sec); | ||
114 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | ||
115 | } | ||
116 | STA_OPS(connected_time); | ||
117 | |||
118 | |||
119 | |||
95 | static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, | 120 | static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, |
96 | size_t count, loff_t *ppos) | 121 | size_t count, loff_t *ppos) |
97 | { | 122 | { |
@@ -324,6 +349,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
324 | DEBUGFS_ADD(flags); | 349 | DEBUGFS_ADD(flags); |
325 | DEBUGFS_ADD(num_ps_buf_frames); | 350 | DEBUGFS_ADD(num_ps_buf_frames); |
326 | DEBUGFS_ADD(inactive_ms); | 351 | DEBUGFS_ADD(inactive_ms); |
352 | DEBUGFS_ADD(connected_time); | ||
327 | DEBUGFS_ADD(last_seq_ctrl); | 353 | DEBUGFS_ADD(last_seq_ctrl); |
328 | DEBUGFS_ADD(agg_status); | 354 | DEBUGFS_ADD(agg_status); |
329 | DEBUGFS_ADD(dev); | 355 | DEBUGFS_ADD(dev); |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 9c0d62bb0ea3..00a0685f2403 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -552,4 +552,17 @@ static inline void drv_get_ringparam(struct ieee80211_local *local, | |||
552 | trace_drv_return_void(local); | 552 | trace_drv_return_void(local); |
553 | } | 553 | } |
554 | 554 | ||
555 | static inline bool drv_tx_frames_pending(struct ieee80211_local *local) | ||
556 | { | ||
557 | bool ret = false; | ||
558 | |||
559 | might_sleep(); | ||
560 | |||
561 | trace_drv_tx_frames_pending(local); | ||
562 | if (local->ops->tx_frames_pending) | ||
563 | ret = local->ops->tx_frames_pending(&local->hw); | ||
564 | trace_drv_return_bool(local, ret); | ||
565 | |||
566 | return ret; | ||
567 | } | ||
555 | #endif /* __MAC80211_DRIVER_OPS */ | 568 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 45aab80738e2..c8c934d48b7a 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -74,6 +74,21 @@ TRACE_EVENT(drv_return_int, | |||
74 | TP_printk(LOCAL_PR_FMT " - %d", LOCAL_PR_ARG, __entry->ret) | 74 | TP_printk(LOCAL_PR_FMT " - %d", LOCAL_PR_ARG, __entry->ret) |
75 | ); | 75 | ); |
76 | 76 | ||
77 | TRACE_EVENT(drv_return_bool, | ||
78 | TP_PROTO(struct ieee80211_local *local, bool ret), | ||
79 | TP_ARGS(local, ret), | ||
80 | TP_STRUCT__entry( | ||
81 | LOCAL_ENTRY | ||
82 | __field(bool, ret) | ||
83 | ), | ||
84 | TP_fast_assign( | ||
85 | LOCAL_ASSIGN; | ||
86 | __entry->ret = ret; | ||
87 | ), | ||
88 | TP_printk(LOCAL_PR_FMT " - %s", LOCAL_PR_ARG, (__entry->ret) ? | ||
89 | "true" : "false") | ||
90 | ); | ||
91 | |||
77 | TRACE_EVENT(drv_return_u64, | 92 | TRACE_EVENT(drv_return_u64, |
78 | TP_PROTO(struct ieee80211_local *local, u64 ret), | 93 | TP_PROTO(struct ieee80211_local *local, u64 ret), |
79 | TP_ARGS(local, ret), | 94 | TP_ARGS(local, ret), |
@@ -964,6 +979,11 @@ TRACE_EVENT(drv_get_ringparam, | |||
964 | ) | 979 | ) |
965 | ); | 980 | ); |
966 | 981 | ||
982 | DEFINE_EVENT(local_only_evt, drv_tx_frames_pending, | ||
983 | TP_PROTO(struct ieee80211_local *local), | ||
984 | TP_ARGS(local) | ||
985 | ); | ||
986 | |||
967 | DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait, | 987 | DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait, |
968 | TP_PROTO(struct ieee80211_local *local), | 988 | TP_PROTO(struct ieee80211_local *local), |
969 | TP_ARGS(local) | 989 | TP_ARGS(local) |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6eb2c8523eeb..8d6d6e3d95da 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -488,8 +488,9 @@ struct ieee80211_if_mesh { | |||
488 | struct mesh_config mshcfg; | 488 | struct mesh_config mshcfg; |
489 | u32 mesh_seqnum; | 489 | u32 mesh_seqnum; |
490 | bool accepting_plinks; | 490 | bool accepting_plinks; |
491 | const u8 *vendor_ie; | 491 | const u8 *ie; |
492 | u8 vendor_ie_len; | 492 | u8 ie_len; |
493 | bool is_secure; | ||
493 | }; | 494 | }; |
494 | 495 | ||
495 | #ifdef CONFIG_MAC80211_MESH | 496 | #ifdef CONFIG_MAC80211_MESH |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index dc50fc3153e5..0ab2a8df312d 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -545,7 +545,9 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { | |||
545 | }, | 545 | }, |
546 | [NL80211_IFTYPE_MESH_POINT] = { | 546 | [NL80211_IFTYPE_MESH_POINT] = { |
547 | .tx = 0xffff, | 547 | .tx = 0xffff, |
548 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4), | 548 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | |
549 | BIT(IEEE80211_STYPE_AUTH >> 4) | | ||
550 | BIT(IEEE80211_STYPE_DEAUTH >> 4), | ||
549 | }, | 551 | }, |
550 | }; | 552 | }; |
551 | 553 | ||
@@ -760,6 +762,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
760 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); | 762 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); |
761 | #endif | 763 | #endif |
762 | 764 | ||
765 | /* if the underlying driver supports mesh, mac80211 will (at least) | ||
766 | * provide routing of mesh authentication frames to userspace */ | ||
767 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) | ||
768 | local->hw.wiphy->flags |= WIPHY_FLAG_MESH_AUTH; | ||
769 | |||
763 | /* mac80211 supports control port protocol changing */ | 770 | /* mac80211 supports control port protocol changing */ |
764 | local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; | 771 | local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; |
765 | 772 | ||
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2a57cc02c618..11207979e2e2 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -279,9 +279,9 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | |||
279 | MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; | 279 | MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; |
280 | *pos++ = 0x00; | 280 | *pos++ = 0x00; |
281 | 281 | ||
282 | if (sdata->u.mesh.vendor_ie) { | 282 | if (sdata->u.mesh.ie) { |
283 | int len = sdata->u.mesh.vendor_ie_len; | 283 | int len = sdata->u.mesh.ie_len; |
284 | const u8 *data = sdata->u.mesh.vendor_ie; | 284 | const u8 *data = sdata->u.mesh.ie; |
285 | if (skb_tailroom(skb) > len) | 285 | if (skb_tailroom(skb) > len) |
286 | memcpy(skb_put(skb, len), data, len); | 286 | memcpy(skb_put(skb, len), data, len); |
287 | } | 287 | } |
@@ -573,6 +573,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
573 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | 573 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, |
574 | &elems); | 574 | &elems); |
575 | 575 | ||
576 | /* ignore beacons from secure mesh peers if our security is off */ | ||
577 | if (elems.rsn_len && !sdata->u.mesh.is_secure) | ||
578 | return; | ||
579 | |||
576 | if (elems.ds_params && elems.ds_params_len == 1) | 580 | if (elems.ds_params && elems.ds_params_len == 1) |
577 | freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); | 581 | freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); |
578 | else | 582 | else |
@@ -586,9 +590,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
586 | if (elems.mesh_id && elems.mesh_config && | 590 | if (elems.mesh_id && elems.mesh_config && |
587 | mesh_matches_local(&elems, sdata)) { | 591 | mesh_matches_local(&elems, sdata)) { |
588 | supp_rates = ieee80211_sta_get_rates(local, &elems, band); | 592 | supp_rates = ieee80211_sta_get_rates(local, &elems, band); |
589 | 593 | mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems); | |
590 | mesh_neighbour_update(mgmt->sa, supp_rates, sdata, | ||
591 | mesh_peer_accepts_plinks(&elems)); | ||
592 | } | 594 | } |
593 | } | 595 | } |
594 | 596 | ||
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index b99e230fe31c..10acf1cc8082 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -226,7 +226,8 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, | |||
226 | int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); | 226 | int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); |
227 | /* Mesh plinks */ | 227 | /* Mesh plinks */ |
228 | void mesh_neighbour_update(u8 *hw_addr, u32 rates, | 228 | void mesh_neighbour_update(u8 *hw_addr, u32 rates, |
229 | struct ieee80211_sub_if_data *sdata, bool add); | 229 | struct ieee80211_sub_if_data *sdata, |
230 | struct ieee802_11_elems *ie); | ||
230 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); | 231 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); |
231 | void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); | 232 | void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); |
232 | void mesh_plink_broken(struct sta_info *sta); | 233 | void mesh_plink_broken(struct sta_info *sta); |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 8d65b47d9837..7776ae5a8f15 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -65,42 +65,37 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | |||
65 | __mesh_table_free(tbl); | 65 | __mesh_table_free(tbl); |
66 | } | 66 | } |
67 | 67 | ||
68 | static struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | 68 | static int mesh_table_grow(struct mesh_table *oldtbl, |
69 | struct mesh_table *newtbl) | ||
69 | { | 70 | { |
70 | struct mesh_table *newtbl; | ||
71 | struct hlist_head *oldhash; | 71 | struct hlist_head *oldhash; |
72 | struct hlist_node *p, *q; | 72 | struct hlist_node *p, *q; |
73 | int i; | 73 | int i; |
74 | 74 | ||
75 | if (atomic_read(&tbl->entries) | 75 | if (atomic_read(&oldtbl->entries) |
76 | < tbl->mean_chain_len * (tbl->hash_mask + 1)) | 76 | < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1)) |
77 | goto endgrow; | 77 | return -EAGAIN; |
78 | 78 | ||
79 | newtbl = mesh_table_alloc(tbl->size_order + 1); | ||
80 | if (!newtbl) | ||
81 | goto endgrow; | ||
82 | 79 | ||
83 | newtbl->free_node = tbl->free_node; | 80 | newtbl->free_node = oldtbl->free_node; |
84 | newtbl->mean_chain_len = tbl->mean_chain_len; | 81 | newtbl->mean_chain_len = oldtbl->mean_chain_len; |
85 | newtbl->copy_node = tbl->copy_node; | 82 | newtbl->copy_node = oldtbl->copy_node; |
86 | atomic_set(&newtbl->entries, atomic_read(&tbl->entries)); | 83 | atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries)); |
87 | 84 | ||
88 | oldhash = tbl->hash_buckets; | 85 | oldhash = oldtbl->hash_buckets; |
89 | for (i = 0; i <= tbl->hash_mask; i++) | 86 | for (i = 0; i <= oldtbl->hash_mask; i++) |
90 | hlist_for_each(p, &oldhash[i]) | 87 | hlist_for_each(p, &oldhash[i]) |
91 | if (tbl->copy_node(p, newtbl) < 0) | 88 | if (oldtbl->copy_node(p, newtbl) < 0) |
92 | goto errcopy; | 89 | goto errcopy; |
93 | 90 | ||
94 | return newtbl; | 91 | return 0; |
95 | 92 | ||
96 | errcopy: | 93 | errcopy: |
97 | for (i = 0; i <= newtbl->hash_mask; i++) { | 94 | for (i = 0; i <= newtbl->hash_mask; i++) { |
98 | hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) | 95 | hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) |
99 | tbl->free_node(p, 0); | 96 | oldtbl->free_node(p, 0); |
100 | } | 97 | } |
101 | __mesh_table_free(newtbl); | 98 | return -ENOMEM; |
102 | endgrow: | ||
103 | return NULL; | ||
104 | } | 99 | } |
105 | 100 | ||
106 | 101 | ||
@@ -334,10 +329,13 @@ void mesh_mpath_table_grow(void) | |||
334 | { | 329 | { |
335 | struct mesh_table *oldtbl, *newtbl; | 330 | struct mesh_table *oldtbl, *newtbl; |
336 | 331 | ||
332 | newtbl = mesh_table_alloc(mesh_paths->size_order + 1); | ||
333 | if (!newtbl) | ||
334 | return; | ||
337 | write_lock(&pathtbl_resize_lock); | 335 | write_lock(&pathtbl_resize_lock); |
338 | oldtbl = mesh_paths; | 336 | oldtbl = mesh_paths; |
339 | newtbl = mesh_table_grow(mesh_paths); | 337 | if (mesh_table_grow(mesh_paths, newtbl) < 0) { |
340 | if (!newtbl) { | 338 | __mesh_table_free(newtbl); |
341 | write_unlock(&pathtbl_resize_lock); | 339 | write_unlock(&pathtbl_resize_lock); |
342 | return; | 340 | return; |
343 | } | 341 | } |
@@ -352,10 +350,13 @@ void mesh_mpp_table_grow(void) | |||
352 | { | 350 | { |
353 | struct mesh_table *oldtbl, *newtbl; | 351 | struct mesh_table *oldtbl, *newtbl; |
354 | 352 | ||
353 | newtbl = mesh_table_alloc(mpp_paths->size_order + 1); | ||
354 | if (!newtbl) | ||
355 | return; | ||
355 | write_lock(&pathtbl_resize_lock); | 356 | write_lock(&pathtbl_resize_lock); |
356 | oldtbl = mpp_paths; | 357 | oldtbl = mpp_paths; |
357 | newtbl = mesh_table_grow(mpp_paths); | 358 | if (mesh_table_grow(mpp_paths, newtbl) < 0) { |
358 | if (!newtbl) { | 359 | __mesh_table_free(newtbl); |
359 | write_unlock(&pathtbl_resize_lock); | 360 | write_unlock(&pathtbl_resize_lock); |
360 | return; | 361 | return; |
361 | } | 362 | } |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 44b53931ba5e..84e5b056af02 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
105 | if (!sta) | 105 | if (!sta) |
106 | return NULL; | 106 | return NULL; |
107 | 107 | ||
108 | sta->flags = WLAN_STA_AUTHORIZED; | 108 | sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH; |
109 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 109 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
110 | rate_control_rate_init(sta); | 110 | rate_control_rate_init(sta); |
111 | 111 | ||
@@ -161,7 +161,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
161 | __le16 reason) { | 161 | __le16 reason) { |
162 | struct ieee80211_local *local = sdata->local; | 162 | struct ieee80211_local *local = sdata->local; |
163 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + | 163 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + |
164 | sdata->u.mesh.vendor_ie_len); | 164 | sdata->u.mesh.ie_len); |
165 | struct ieee80211_mgmt *mgmt; | 165 | struct ieee80211_mgmt *mgmt; |
166 | bool include_plid = false; | 166 | bool include_plid = false; |
167 | static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; | 167 | static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; |
@@ -237,8 +237,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
237 | return 0; | 237 | return 0; |
238 | } | 238 | } |
239 | 239 | ||
240 | void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata, | 240 | void mesh_neighbour_update(u8 *hw_addr, u32 rates, |
241 | bool peer_accepting_plinks) | 241 | struct ieee80211_sub_if_data *sdata, |
242 | struct ieee802_11_elems *elems) | ||
242 | { | 243 | { |
243 | struct ieee80211_local *local = sdata->local; | 244 | struct ieee80211_local *local = sdata->local; |
244 | struct sta_info *sta; | 245 | struct sta_info *sta; |
@@ -248,8 +249,14 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data | |||
248 | sta = sta_info_get(sdata, hw_addr); | 249 | sta = sta_info_get(sdata, hw_addr); |
249 | if (!sta) { | 250 | if (!sta) { |
250 | rcu_read_unlock(); | 251 | rcu_read_unlock(); |
251 | 252 | /* Userspace handles peer allocation when security is enabled | |
252 | sta = mesh_plink_alloc(sdata, hw_addr, rates); | 253 | * */ |
254 | if (sdata->u.mesh.is_secure) | ||
255 | cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, | ||
256 | elems->ie_start, elems->total_len, | ||
257 | GFP_KERNEL); | ||
258 | else | ||
259 | sta = mesh_plink_alloc(sdata, hw_addr, rates); | ||
253 | if (!sta) | 260 | if (!sta) |
254 | return; | 261 | return; |
255 | if (sta_info_insert_rcu(sta)) { | 262 | if (sta_info_insert_rcu(sta)) { |
@@ -260,7 +267,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data | |||
260 | 267 | ||
261 | sta->last_rx = jiffies; | 268 | sta->last_rx = jiffies; |
262 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 269 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
263 | if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN && | 270 | if (mesh_peer_accepts_plinks(elems) && |
271 | sta->plink_state == PLINK_LISTEN && | ||
264 | sdata->u.mesh.accepting_plinks && | 272 | sdata->u.mesh.accepting_plinks && |
265 | sdata->u.mesh.mshcfg.auto_open_plinks) | 273 | sdata->u.mesh.mshcfg.auto_open_plinks) |
266 | mesh_plink_open(sta); | 274 | mesh_plink_open(sta); |
@@ -372,6 +380,9 @@ int mesh_plink_open(struct sta_info *sta) | |||
372 | __le16 llid; | 380 | __le16 llid; |
373 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 381 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
374 | 382 | ||
383 | if (!test_sta_flags(sta, WLAN_STA_AUTH)) | ||
384 | return -EPERM; | ||
385 | |||
375 | spin_lock_bh(&sta->lock); | 386 | spin_lock_bh(&sta->lock); |
376 | get_random_bytes(&llid, 2); | 387 | get_random_bytes(&llid, 2); |
377 | sta->llid = llid; | 388 | sta->llid = llid; |
@@ -449,6 +460,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
449 | mpl_dbg("Mesh plink: missing necessary peer link ie\n"); | 460 | mpl_dbg("Mesh plink: missing necessary peer link ie\n"); |
450 | return; | 461 | return; |
451 | } | 462 | } |
463 | if (elems.rsn_len && !sdata->u.mesh.is_secure) { | ||
464 | mpl_dbg("Mesh plink: can't establish link with secure peer\n"); | ||
465 | return; | ||
466 | } | ||
452 | 467 | ||
453 | ftype = mgmt->u.action.u.plink_action.action_code; | 468 | ftype = mgmt->u.action.u.plink_action.action_code; |
454 | ie_len = elems.peer_link_len; | 469 | ie_len = elems.peer_link_len; |
@@ -480,6 +495,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
480 | return; | 495 | return; |
481 | } | 496 | } |
482 | 497 | ||
498 | if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) { | ||
499 | mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); | ||
500 | rcu_read_unlock(); | ||
501 | return; | ||
502 | } | ||
503 | |||
483 | if (sta && sta->plink_state == PLINK_BLOCKED) { | 504 | if (sta && sta->plink_state == PLINK_BLOCKED) { |
484 | rcu_read_unlock(); | 505 | rcu_read_unlock(); |
485 | return; | 506 | return; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 865fed4cc18b..a41f234bd486 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -761,15 +761,16 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | |||
761 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && | 761 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && |
762 | (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { | 762 | (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { |
763 | netif_tx_stop_all_queues(sdata->dev); | 763 | netif_tx_stop_all_queues(sdata->dev); |
764 | /* | ||
765 | * Flush all the frames queued in the driver before | ||
766 | * going to power save | ||
767 | */ | ||
768 | drv_flush(local, false); | ||
769 | ieee80211_send_nullfunc(local, sdata, 1); | ||
770 | 764 | ||
771 | /* Flush once again to get the tx status of nullfunc frame */ | 765 | if (drv_tx_frames_pending(local)) |
772 | drv_flush(local, false); | 766 | mod_timer(&local->dynamic_ps_timer, jiffies + |
767 | msecs_to_jiffies( | ||
768 | local->hw.conf.dynamic_ps_timeout)); | ||
769 | else { | ||
770 | ieee80211_send_nullfunc(local, sdata, 1); | ||
771 | /* Flush to get the tx status of nullfunc frame */ | ||
772 | drv_flush(local, false); | ||
773 | } | ||
773 | } | 774 | } |
774 | 775 | ||
775 | if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && | 776 | if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fc2ff78582ca..54858a68abd7 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -502,7 +502,8 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
502 | 502 | ||
503 | if (ieee80211_is_probe_req(hdr->frame_control) || | 503 | if (ieee80211_is_probe_req(hdr->frame_control) || |
504 | ieee80211_is_probe_resp(hdr->frame_control) || | 504 | ieee80211_is_probe_resp(hdr->frame_control) || |
505 | ieee80211_is_beacon(hdr->frame_control)) | 505 | ieee80211_is_beacon(hdr->frame_control) || |
506 | ieee80211_is_auth(hdr->frame_control)) | ||
506 | return RX_CONTINUE; | 507 | return RX_CONTINUE; |
507 | 508 | ||
508 | return RX_DROP_MONITOR; | 509 | return RX_DROP_MONITOR; |
@@ -1585,7 +1586,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) | |||
1585 | } | 1586 | } |
1586 | 1587 | ||
1587 | static int | 1588 | static int |
1588 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | 1589 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control) |
1589 | { | 1590 | { |
1590 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1591 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1591 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1592 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
@@ -1593,6 +1594,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1593 | struct ethhdr *ehdr; | 1594 | struct ethhdr *ehdr; |
1594 | int ret; | 1595 | int ret; |
1595 | 1596 | ||
1597 | *port_control = false; | ||
1596 | if (ieee80211_has_a4(hdr->frame_control) && | 1598 | if (ieee80211_has_a4(hdr->frame_control) && |
1597 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) | 1599 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) |
1598 | return -1; | 1600 | return -1; |
@@ -1611,11 +1613,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1611 | return -1; | 1613 | return -1; |
1612 | 1614 | ||
1613 | ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); | 1615 | ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); |
1614 | if (ret < 0 || !check_port_control) | 1616 | if (ret < 0) |
1615 | return ret; | 1617 | return ret; |
1616 | 1618 | ||
1617 | ehdr = (struct ethhdr *) rx->skb->data; | 1619 | ehdr = (struct ethhdr *) rx->skb->data; |
1618 | if (ehdr->h_proto != rx->sdata->control_port_protocol) | 1620 | if (ehdr->h_proto == rx->sdata->control_port_protocol) |
1621 | *port_control = true; | ||
1622 | else if (check_port_control) | ||
1619 | return -1; | 1623 | return -1; |
1620 | 1624 | ||
1621 | return 0; | 1625 | return 0; |
@@ -1916,6 +1920,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
1916 | struct net_device *dev = sdata->dev; | 1920 | struct net_device *dev = sdata->dev; |
1917 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1921 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
1918 | __le16 fc = hdr->frame_control; | 1922 | __le16 fc = hdr->frame_control; |
1923 | bool port_control; | ||
1919 | int err; | 1924 | int err; |
1920 | 1925 | ||
1921 | if (unlikely(!ieee80211_is_data(hdr->frame_control))) | 1926 | if (unlikely(!ieee80211_is_data(hdr->frame_control))) |
@@ -1932,13 +1937,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
1932 | sdata->vif.type == NL80211_IFTYPE_AP) | 1937 | sdata->vif.type == NL80211_IFTYPE_AP) |
1933 | return RX_DROP_MONITOR; | 1938 | return RX_DROP_MONITOR; |
1934 | 1939 | ||
1935 | err = __ieee80211_data_to_8023(rx); | 1940 | err = __ieee80211_data_to_8023(rx, &port_control); |
1936 | if (unlikely(err)) | 1941 | if (unlikely(err)) |
1937 | return RX_DROP_UNUSABLE; | 1942 | return RX_DROP_UNUSABLE; |
1938 | 1943 | ||
1939 | if (!ieee80211_frame_allowed(rx, fc)) | 1944 | if (!ieee80211_frame_allowed(rx, fc)) |
1940 | return RX_DROP_MONITOR; | 1945 | return RX_DROP_MONITOR; |
1941 | 1946 | ||
1947 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && | ||
1948 | unlikely(port_control) && sdata->bss) { | ||
1949 | sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, | ||
1950 | u.ap); | ||
1951 | dev = sdata->dev; | ||
1952 | rx->sdata = sdata; | ||
1953 | } | ||
1954 | |||
1942 | rx->skb->dev = dev; | 1955 | rx->skb->dev = dev; |
1943 | 1956 | ||
1944 | dev->stats.rx_packets++; | 1957 | dev->stats.rx_packets++; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 999f8fbf0b4b..8a9068ac0673 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -228,6 +228,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
228 | { | 228 | { |
229 | struct ieee80211_local *local = sdata->local; | 229 | struct ieee80211_local *local = sdata->local; |
230 | struct sta_info *sta; | 230 | struct sta_info *sta; |
231 | struct timespec uptime; | ||
231 | int i; | 232 | int i; |
232 | 233 | ||
233 | sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); | 234 | sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); |
@@ -245,6 +246,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
245 | sta->sdata = sdata; | 246 | sta->sdata = sdata; |
246 | sta->last_rx = jiffies; | 247 | sta->last_rx = jiffies; |
247 | 248 | ||
249 | do_posix_clock_monotonic_gettime(&uptime); | ||
250 | sta->last_connected = uptime.tv_sec; | ||
248 | ewma_init(&sta->avg_signal, 1024, 8); | 251 | ewma_init(&sta->avg_signal, 1024, 8); |
249 | 252 | ||
250 | if (sta_prepare_rate_control(local, sta, gfp)) { | 253 | if (sta_prepare_rate_control(local, sta, gfp)) { |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 43238e99cfb3..984a03db3553 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -226,6 +226,7 @@ enum plink_state { | |||
226 | * @rx_bytes: Number of bytes received from this STA | 226 | * @rx_bytes: Number of bytes received from this STA |
227 | * @wep_weak_iv_count: number of weak WEP IVs received from this station | 227 | * @wep_weak_iv_count: number of weak WEP IVs received from this station |
228 | * @last_rx: time (in jiffies) when last frame was received from this STA | 228 | * @last_rx: time (in jiffies) when last frame was received from this STA |
229 | * @last_connected: time (in seconds) when a station got connected | ||
229 | * @num_duplicates: number of duplicate frames received from this STA | 230 | * @num_duplicates: number of duplicate frames received from this STA |
230 | * @rx_fragments: number of received MPDUs | 231 | * @rx_fragments: number of received MPDUs |
231 | * @rx_dropped: number of dropped MPDUs from this STA | 232 | * @rx_dropped: number of dropped MPDUs from this STA |
@@ -295,6 +296,7 @@ struct sta_info { | |||
295 | unsigned long rx_packets, rx_bytes; | 296 | unsigned long rx_packets, rx_bytes; |
296 | unsigned long wep_weak_iv_count; | 297 | unsigned long wep_weak_iv_count; |
297 | unsigned long last_rx; | 298 | unsigned long last_rx; |
299 | long last_connected; | ||
298 | unsigned long num_duplicates; | 300 | unsigned long num_duplicates; |
299 | unsigned long rx_fragments; | 301 | unsigned long rx_fragments; |
300 | unsigned long rx_dropped; | 302 | unsigned long rx_dropped; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ce4596ed1268..17b10be31f55 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2262,7 +2262,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2262 | 2262 | ||
2263 | /* headroom, head length, tail length and maximum TIM length */ | 2263 | /* headroom, head length, tail length and maximum TIM length */ |
2264 | skb = dev_alloc_skb(local->tx_headroom + 400 + | 2264 | skb = dev_alloc_skb(local->tx_headroom + 400 + |
2265 | sdata->u.mesh.vendor_ie_len); | 2265 | sdata->u.mesh.ie_len); |
2266 | if (!skb) | 2266 | if (!skb) |
2267 | goto out; | 2267 | goto out; |
2268 | 2268 | ||
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 73e39c171ffb..5c116083eeca 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <linux/ieee80211.h> | 1 | #include <linux/ieee80211.h> |
2 | #include <net/cfg80211.h> | 2 | #include <net/cfg80211.h> |
3 | #include "nl80211.h" | ||
3 | #include "core.h" | 4 | #include "core.h" |
4 | 5 | ||
5 | /* Default values, timeouts in ms */ | 6 | /* Default values, timeouts in ms */ |
@@ -53,8 +54,9 @@ const struct mesh_config default_mesh_config = { | |||
53 | const struct mesh_setup default_mesh_setup = { | 54 | const struct mesh_setup default_mesh_setup = { |
54 | .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, | 55 | .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, |
55 | .path_metric = IEEE80211_PATH_METRIC_AIRTIME, | 56 | .path_metric = IEEE80211_PATH_METRIC_AIRTIME, |
56 | .vendor_ie = NULL, | 57 | .ie = NULL, |
57 | .vendor_ie_len = 0, | 58 | .ie_len = 0, |
59 | .is_secure = false, | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | 62 | int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, |
@@ -72,6 +74,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
72 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 74 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
73 | return -EOPNOTSUPP; | 75 | return -EOPNOTSUPP; |
74 | 76 | ||
77 | if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && | ||
78 | setup->is_secure) | ||
79 | return -EOPNOTSUPP; | ||
80 | |||
75 | if (wdev->mesh_id_len) | 81 | if (wdev->mesh_id_len) |
76 | return -EALREADY; | 82 | return -EALREADY; |
77 | 83 | ||
@@ -105,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
105 | return err; | 111 | return err; |
106 | } | 112 | } |
107 | 113 | ||
114 | void cfg80211_notify_new_peer_candidate(struct net_device *dev, | ||
115 | const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp) | ||
116 | { | ||
117 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
118 | |||
119 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) | ||
120 | return; | ||
121 | |||
122 | nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev, | ||
123 | macaddr, ie, ie_len, gfp); | ||
124 | } | ||
125 | EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate); | ||
126 | |||
108 | static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 127 | static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, |
109 | struct net_device *dev) | 128 | struct net_device *dev) |
110 | { | 129 | { |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 297d7ce4117b..0efa7fd01150 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -124,6 +124,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
124 | [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, | 124 | [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, |
125 | 125 | ||
126 | [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, | 126 | [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, |
127 | [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, | ||
127 | 128 | ||
128 | [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, | 129 | [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, |
129 | .len = NL80211_HT_CAPABILITY_LEN }, | 130 | .len = NL80211_HT_CAPABILITY_LEN }, |
@@ -594,6 +595,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
594 | 595 | ||
595 | if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) | 596 | if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) |
596 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); | 597 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); |
598 | if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) | ||
599 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); | ||
597 | 600 | ||
598 | NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, | 601 | NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, |
599 | sizeof(u32) * dev->wiphy.n_cipher_suites, | 602 | sizeof(u32) * dev->wiphy.n_cipher_suites, |
@@ -1922,6 +1925,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { | |||
1922 | [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, | 1925 | [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, |
1923 | [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, | 1926 | [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, |
1924 | [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, | 1927 | [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, |
1928 | [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG }, | ||
1925 | }; | 1929 | }; |
1926 | 1930 | ||
1927 | static int parse_station_flags(struct genl_info *info, | 1931 | static int parse_station_flags(struct genl_info *info, |
@@ -2016,6 +2020,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, | |||
2016 | sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); | 2020 | sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); |
2017 | if (!sinfoattr) | 2021 | if (!sinfoattr) |
2018 | goto nla_put_failure; | 2022 | goto nla_put_failure; |
2023 | if (sinfo->filled & STATION_INFO_CONNECTED_TIME) | ||
2024 | NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME, | ||
2025 | sinfo->connected_time); | ||
2019 | if (sinfo->filled & STATION_INFO_INACTIVE_TIME) | 2026 | if (sinfo->filled & STATION_INFO_INACTIVE_TIME) |
2020 | NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, | 2027 | NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, |
2021 | sinfo->inactive_time); | 2028 | sinfo->inactive_time); |
@@ -2281,7 +2288,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
2281 | err = -EINVAL; | 2288 | err = -EINVAL; |
2282 | if (params.supported_rates) | 2289 | if (params.supported_rates) |
2283 | err = -EINVAL; | 2290 | err = -EINVAL; |
2284 | if (params.sta_flags_mask) | 2291 | if (params.sta_flags_mask & |
2292 | ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | | ||
2293 | BIT(NL80211_STA_FLAG_AUTHORIZED))) | ||
2285 | err = -EINVAL; | 2294 | err = -EINVAL; |
2286 | break; | 2295 | break; |
2287 | default: | 2296 | default: |
@@ -2343,11 +2352,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
2343 | params.ht_capa = | 2352 | params.ht_capa = |
2344 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | 2353 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); |
2345 | 2354 | ||
2355 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) | ||
2356 | params.plink_action = | ||
2357 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); | ||
2358 | |||
2346 | if (parse_station_flags(info, ¶ms)) | 2359 | if (parse_station_flags(info, ¶ms)) |
2347 | return -EINVAL; | 2360 | return -EINVAL; |
2348 | 2361 | ||
2349 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 2362 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
2350 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 2363 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && |
2364 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && | ||
2351 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 2365 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
2352 | return -EINVAL; | 2366 | return -EINVAL; |
2353 | 2367 | ||
@@ -2823,7 +2837,8 @@ static const struct nla_policy | |||
2823 | nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { | 2837 | nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { |
2824 | [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, | 2838 | [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, |
2825 | [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, | 2839 | [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, |
2826 | [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY, | 2840 | [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, |
2841 | [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, | ||
2827 | .len = IEEE80211_MAX_DATA_LEN }, | 2842 | .len = IEEE80211_MAX_DATA_LEN }, |
2828 | }; | 2843 | }; |
2829 | 2844 | ||
@@ -2925,14 +2940,16 @@ static int nl80211_parse_mesh_setup(struct genl_info *info, | |||
2925 | IEEE80211_PATH_METRIC_VENDOR : | 2940 | IEEE80211_PATH_METRIC_VENDOR : |
2926 | IEEE80211_PATH_METRIC_AIRTIME; | 2941 | IEEE80211_PATH_METRIC_AIRTIME; |
2927 | 2942 | ||
2928 | if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) { | 2943 | |
2944 | if (tb[NL80211_MESH_SETUP_IE]) { | ||
2929 | struct nlattr *ieattr = | 2945 | struct nlattr *ieattr = |
2930 | tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]; | 2946 | tb[NL80211_MESH_SETUP_IE]; |
2931 | if (!is_valid_ie_attr(ieattr)) | 2947 | if (!is_valid_ie_attr(ieattr)) |
2932 | return -EINVAL; | 2948 | return -EINVAL; |
2933 | setup->vendor_ie = nla_data(ieattr); | 2949 | setup->ie = nla_data(ieattr); |
2934 | setup->vendor_ie_len = nla_len(ieattr); | 2950 | setup->ie_len = nla_len(ieattr); |
2935 | } | 2951 | } |
2952 | setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); | ||
2936 | 2953 | ||
2937 | return 0; | 2954 | return 0; |
2938 | } | 2955 | } |
@@ -5804,6 +5821,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, | |||
5804 | nlmsg_free(msg); | 5821 | nlmsg_free(msg); |
5805 | } | 5822 | } |
5806 | 5823 | ||
5824 | void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, | ||
5825 | struct net_device *netdev, | ||
5826 | const u8 *macaddr, const u8* ie, u8 ie_len, | ||
5827 | gfp_t gfp) | ||
5828 | { | ||
5829 | struct sk_buff *msg; | ||
5830 | void *hdr; | ||
5831 | |||
5832 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | ||
5833 | if (!msg) | ||
5834 | return; | ||
5835 | |||
5836 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE); | ||
5837 | if (!hdr) { | ||
5838 | nlmsg_free(msg); | ||
5839 | return; | ||
5840 | } | ||
5841 | |||
5842 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
5843 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | ||
5844 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr); | ||
5845 | if (ie_len && ie) | ||
5846 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); | ||
5847 | |||
5848 | if (genlmsg_end(msg, hdr) < 0) { | ||
5849 | nlmsg_free(msg); | ||
5850 | return; | ||
5851 | } | ||
5852 | |||
5853 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
5854 | nl80211_mlme_mcgrp.id, gfp); | ||
5855 | return; | ||
5856 | |||
5857 | nla_put_failure: | ||
5858 | genlmsg_cancel(msg, hdr); | ||
5859 | nlmsg_free(msg); | ||
5860 | } | ||
5861 | |||
5807 | void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | 5862 | void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, |
5808 | struct net_device *netdev, const u8 *addr, | 5863 | struct net_device *netdev, const u8 *addr, |
5809 | enum nl80211_key_type key_type, int key_id, | 5864 | enum nl80211_key_type key_type, int key_id, |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index dcac5cd6f017..f2af6955a665 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -50,6 +50,10 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, | |||
50 | struct net_device *netdev, u16 reason, | 50 | struct net_device *netdev, u16 reason, |
51 | const u8 *ie, size_t ie_len, bool from_ap); | 51 | const u8 *ie, size_t ie_len, bool from_ap); |
52 | 52 | ||
53 | void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, | ||
54 | struct net_device *netdev, | ||
55 | const u8 *macaddr, const u8* ie, u8 ie_len, | ||
56 | gfp_t gfp); | ||
53 | void | 57 | void |
54 | nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | 58 | nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, |
55 | struct net_device *netdev, const u8 *addr, | 59 | struct net_device *netdev, const u8 *addr, |