aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/carl9170
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/carl9170')
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h5
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h13
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h7
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c56
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c19
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c17
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.h24
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c80
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h6
10 files changed, 157 insertions, 72 deletions
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 6cf0c9ef47aa..d07ff7f2fd92 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -48,7 +48,7 @@
48#include <linux/usb.h> 48#include <linux/usb.h>
49#ifdef CONFIG_CARL9170_LEDS 49#ifdef CONFIG_CARL9170_LEDS
50#include <linux/leds.h> 50#include <linux/leds.h>
51#endif /* CONFIG_CARL170_LEDS */ 51#endif /* CONFIG_CARL9170_LEDS */
52#ifdef CONFIG_CARL9170_WPC 52#ifdef CONFIG_CARL9170_WPC
53#include <linux/input.h> 53#include <linux/input.h>
54#endif /* CONFIG_CARL9170_WPC */ 54#endif /* CONFIG_CARL9170_WPC */
@@ -215,7 +215,7 @@ enum carl9170_restart_reasons {
215 CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS, 215 CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS,
216 CARL9170_RR_WATCHDOG, 216 CARL9170_RR_WATCHDOG,
217 CARL9170_RR_STUCK_TX, 217 CARL9170_RR_STUCK_TX,
218 CARL9170_RR_SLOW_SYSTEM, 218 CARL9170_RR_UNRESPONSIVE_DEVICE,
219 CARL9170_RR_COMMAND_TIMEOUT, 219 CARL9170_RR_COMMAND_TIMEOUT,
220 CARL9170_RR_TOO_MANY_PHY_ERRORS, 220 CARL9170_RR_TOO_MANY_PHY_ERRORS,
221 CARL9170_RR_LOST_RSP, 221 CARL9170_RR_LOST_RSP,
@@ -287,6 +287,7 @@ struct ar9170 {
287 287
288 /* reset / stuck frames/queue detection */ 288 /* reset / stuck frames/queue detection */
289 struct work_struct restart_work; 289 struct work_struct restart_work;
290 struct work_struct ping_work;
290 unsigned int restart_counter; 291 unsigned int restart_counter;
291 unsigned long queue_stop_timeout[__AR9170_NUM_TXQ]; 292 unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
292 unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ]; 293 unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
index d552166db505..3680dfc70f46 100644
--- a/drivers/net/wireless/ath/carl9170/fwcmd.h
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -97,13 +97,13 @@ struct carl9170_set_key_cmd {
97 __le16 type; 97 __le16 type;
98 u8 macAddr[6]; 98 u8 macAddr[6];
99 u32 key[4]; 99 u32 key[4];
100} __packed; 100} __packed __aligned(4);
101#define CARL9170_SET_KEY_CMD_SIZE 28 101#define CARL9170_SET_KEY_CMD_SIZE 28
102 102
103struct carl9170_disable_key_cmd { 103struct carl9170_disable_key_cmd {
104 __le16 user; 104 __le16 user;
105 __le16 padding; 105 __le16 padding;
106} __packed; 106} __packed __aligned(4);
107#define CARL9170_DISABLE_KEY_CMD_SIZE 4 107#define CARL9170_DISABLE_KEY_CMD_SIZE 4
108 108
109struct carl9170_u32_list { 109struct carl9170_u32_list {
@@ -206,7 +206,7 @@ struct carl9170_cmd {
206 struct carl9170_rx_filter_cmd rx_filter; 206 struct carl9170_rx_filter_cmd rx_filter;
207 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; 207 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
208 } __packed; 208 } __packed;
209} __packed; 209} __packed __aligned(4);
210 210
211#define CARL9170_TX_STATUS_QUEUE 3 211#define CARL9170_TX_STATUS_QUEUE 3
212#define CARL9170_TX_STATUS_QUEUE_S 0 212#define CARL9170_TX_STATUS_QUEUE_S 0
@@ -216,6 +216,7 @@ struct carl9170_cmd {
216#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S) 216#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S)
217#define CARL9170_TX_STATUS_SUCCESS 0x80 217#define CARL9170_TX_STATUS_SUCCESS 0x80
218 218
219#ifdef __CARL9170FW__
219/* 220/*
220 * NOTE: 221 * NOTE:
221 * Both structs [carl9170_tx_status and _carl9170_tx_status] 222 * Both structs [carl9170_tx_status and _carl9170_tx_status]
@@ -232,6 +233,8 @@ struct carl9170_tx_status {
232 u8 tries:3; 233 u8 tries:3;
233 u8 success:1; 234 u8 success:1;
234} __packed; 235} __packed;
236#endif /* __CARL9170FW__ */
237
235struct _carl9170_tx_status { 238struct _carl9170_tx_status {
236 /* 239 /*
237 * This version should be immune to all alignment bugs. 240 * This version should be immune to all alignment bugs.
@@ -272,13 +275,15 @@ struct carl9170_rsp {
272 struct carl9170_rf_init_result rf_init_res; 275 struct carl9170_rf_init_result rf_init_res;
273 struct carl9170_u32_list rreg_res; 276 struct carl9170_u32_list rreg_res;
274 struct carl9170_u32_list echo; 277 struct carl9170_u32_list echo;
278#ifdef __CARL9170FW__
275 struct carl9170_tx_status tx_status[0]; 279 struct carl9170_tx_status tx_status[0];
280#endif /* __CARL9170FW__ */
276 struct _carl9170_tx_status _tx_status[0]; 281 struct _carl9170_tx_status _tx_status[0];
277 struct carl9170_gpio gpio; 282 struct carl9170_gpio gpio;
278 struct carl9170_tsf_rsp tsf; 283 struct carl9170_tsf_rsp tsf;
279 struct carl9170_psm psm; 284 struct carl9170_psm psm;
280 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; 285 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
281 } __packed; 286 } __packed;
282} __packed; 287} __packed __aligned(4);
283 288
284#endif /* __CARL9170_SHARED_FWCMD_H */ 289#endif /* __CARL9170_SHARED_FWCMD_H */
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
index 2f471b3f05af..e85df6edfed3 100644
--- a/drivers/net/wireless/ath/carl9170/hw.h
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -712,7 +712,8 @@ struct ar9170_stream {
712 __le16 tag; 712 __le16 tag;
713 713
714 u8 payload[0]; 714 u8 payload[0];
715}; 715} __packed __aligned(4);
716#define AR9170_STREAM_LEN 4
716 717
717#define AR9170_MAX_ACKTABLE_ENTRIES 8 718#define AR9170_MAX_ACKTABLE_ENTRIES 8
718#define AR9170_MAX_VIRTUAL_MAC 7 719#define AR9170_MAX_VIRTUAL_MAC 7
@@ -736,4 +737,8 @@ struct ar9170_stream {
736 737
737#define MOD_VAL(reg, value, newvalue) \ 738#define MOD_VAL(reg, value, newvalue) \
738 (((value) & ~reg) | (((newvalue) << reg##_S) & reg)) 739 (((value) & ~reg) | (((newvalue) << reg##_S) & reg))
740
741#define GET_VAL(reg, value) \
742 (((value) & reg) >> reg##_S)
743
739#endif /* __CARL9170_SHARED_HW_H */ 744#endif /* __CARL9170_SHARED_HW_H */
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 2305bc27151c..385cf508479b 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -205,8 +205,8 @@ int carl9170_init_mac(struct ar9170 *ar)
205 carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105); 205 carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
206 206
207 /* Aggregation MAX number and timeout */ 207 /* Aggregation MAX number and timeout */
208 carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa); 208 carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a);
209 carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00); 209 carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07);
210 210
211 carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, 211 carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
212 AR9170_MAC_FTF_DEFAULTS); 212 AR9170_MAC_FTF_DEFAULTS);
@@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
457 457
458int carl9170_update_beacon(struct ar9170 *ar, const bool submit) 458int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
459{ 459{
460 struct sk_buff *skb; 460 struct sk_buff *skb = NULL;
461 struct carl9170_vif_info *cvif; 461 struct carl9170_vif_info *cvif;
462 struct ieee80211_tx_info *txinfo;
462 __le32 *data, *old = NULL; 463 __le32 *data, *old = NULL;
463 u32 word, off, addr, len; 464 u32 word, off, addr, len;
464 int i = 0, err = 0; 465 int i = 0, err = 0;
@@ -487,7 +488,13 @@ found:
487 488
488 if (!skb) { 489 if (!skb) {
489 err = -ENOMEM; 490 err = -ENOMEM;
490 goto out_unlock; 491 goto err_free;
492 }
493
494 txinfo = IEEE80211_SKB_CB(skb);
495 if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
496 err = -EINVAL;
497 goto err_free;
491 } 498 }
492 499
493 spin_lock_bh(&ar->beacon_lock); 500 spin_lock_bh(&ar->beacon_lock);
@@ -504,11 +511,8 @@ found:
504 wiphy_err(ar->hw->wiphy, "beacon does not " 511 wiphy_err(ar->hw->wiphy, "beacon does not "
505 "fit into device memory!\n"); 512 "fit into device memory!\n");
506 } 513 }
507
508 spin_unlock_bh(&ar->beacon_lock);
509 dev_kfree_skb_any(skb);
510 err = -EINVAL; 514 err = -EINVAL;
511 goto out_unlock; 515 goto err_unlock;
512 } 516 }
513 517
514 if (len > AR9170_MAC_BCN_LENGTH_MAX) { 518 if (len > AR9170_MAC_BCN_LENGTH_MAX) {
@@ -518,22 +522,22 @@ found:
518 AR9170_MAC_BCN_LENGTH_MAX, len); 522 AR9170_MAC_BCN_LENGTH_MAX, len);
519 } 523 }
520 524
521 spin_unlock_bh(&ar->beacon_lock);
522 dev_kfree_skb_any(skb);
523 err = -EMSGSIZE; 525 err = -EMSGSIZE;
524 goto out_unlock; 526 goto err_unlock;
525 } 527 }
526 528
527 carl9170_async_regwrite_begin(ar); 529 i = txinfo->control.rates[0].idx;
530 if (txinfo->band != IEEE80211_BAND_2GHZ)
531 i += 4;
528 532
529 /* XXX: use skb->cb info */ 533 word = __carl9170_ratetable[i].hw_value & 0xf;
530 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { 534 if (i < 4)
531 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, 535 word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
532 ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400); 536 else
533 } else { 537 word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
534 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, 538
535 ((skb->len + FCS_LEN) << 16) + 0x001b); 539 carl9170_async_regwrite_begin(ar);
536 } 540 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
537 541
538 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { 542 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
539 /* 543 /*
@@ -557,7 +561,7 @@ found:
557 cvif->beacon = skb; 561 cvif->beacon = skb;
558 spin_unlock_bh(&ar->beacon_lock); 562 spin_unlock_bh(&ar->beacon_lock);
559 if (err) 563 if (err)
560 goto out_unlock; 564 goto err_free;
561 565
562 if (submit) { 566 if (submit) {
563 err = carl9170_bcn_ctrl(ar, cvif->id, 567 err = carl9170_bcn_ctrl(ar, cvif->id,
@@ -565,10 +569,18 @@ found:
565 addr, skb->len + FCS_LEN); 569 addr, skb->len + FCS_LEN);
566 570
567 if (err) 571 if (err)
568 goto out_unlock; 572 goto err_free;
569 } 573 }
570out_unlock: 574out_unlock:
571 rcu_read_unlock(); 575 rcu_read_unlock();
576 return 0;
577
578err_unlock:
579 spin_unlock_bh(&ar->beacon_lock);
580
581err_free:
582 rcu_read_unlock();
583 dev_kfree_skb_any(skb);
572 return err; 584 return err;
573} 585}
574 586
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 980ae70ea424..4ae6a5849076 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -428,6 +428,7 @@ static void carl9170_cancel_worker(struct ar9170 *ar)
428 cancel_delayed_work_sync(&ar->led_work); 428 cancel_delayed_work_sync(&ar->led_work);
429#endif /* CONFIG_CARL9170_LEDS */ 429#endif /* CONFIG_CARL9170_LEDS */
430 cancel_work_sync(&ar->ps_work); 430 cancel_work_sync(&ar->ps_work);
431 cancel_work_sync(&ar->ping_work);
431 cancel_work_sync(&ar->ampdu_work); 432 cancel_work_sync(&ar->ampdu_work);
432} 433}
433 434
@@ -533,6 +534,21 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
533 */ 534 */
534} 535}
535 536
537static void carl9170_ping_work(struct work_struct *work)
538{
539 struct ar9170 *ar = container_of(work, struct ar9170, ping_work);
540 int err;
541
542 if (!IS_STARTED(ar))
543 return;
544
545 mutex_lock(&ar->mutex);
546 err = carl9170_echo_test(ar, 0xdeadbeef);
547 if (err)
548 carl9170_restart(ar, CARL9170_RR_UNRESPONSIVE_DEVICE);
549 mutex_unlock(&ar->mutex);
550}
551
536static int carl9170_init_interface(struct ar9170 *ar, 552static int carl9170_init_interface(struct ar9170 *ar,
537 struct ieee80211_vif *vif) 553 struct ieee80211_vif *vif)
538{ 554{
@@ -1614,6 +1630,7 @@ void *carl9170_alloc(size_t priv_size)
1614 skb_queue_head_init(&ar->tx_pending[i]); 1630 skb_queue_head_init(&ar->tx_pending[i]);
1615 } 1631 }
1616 INIT_WORK(&ar->ps_work, carl9170_ps_work); 1632 INIT_WORK(&ar->ps_work, carl9170_ps_work);
1633 INIT_WORK(&ar->ping_work, carl9170_ping_work);
1617 INIT_WORK(&ar->restart_work, carl9170_restart_work); 1634 INIT_WORK(&ar->restart_work, carl9170_restart_work);
1618 INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work); 1635 INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work);
1619 INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor); 1636 INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor);
@@ -1828,7 +1845,7 @@ int carl9170_register(struct ar9170 *ar)
1828 err = carl9170_led_register(ar); 1845 err = carl9170_led_register(ar);
1829 if (err) 1846 if (err)
1830 goto err_unreg; 1847 goto err_unreg;
1831#endif /* CONFIG_CAR9L170_LEDS */ 1848#endif /* CONFIG_CARL9170_LEDS */
1832 1849
1833#ifdef CONFIG_CARL9170_WPC 1850#ifdef CONFIG_CARL9170_WPC
1834 err = carl9170_register_wps_button(ar); 1851 err = carl9170_register_wps_button(ar);
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index 89deca37a988..82bc81c4c930 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1554,15 +1554,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
1554 return carl9170_regwrite_result(); 1554 return carl9170_regwrite_result();
1555} 1555}
1556 1556
1557/* TODO: replace this with sign_extend32(noise, 8) */
1558static int carl9170_calc_noise_dbm(u32 raw_noise)
1559{
1560 if (raw_noise & 0x100)
1561 return ~0x1ff | raw_noise;
1562 else
1563 return raw_noise;
1564}
1565
1566int carl9170_get_noisefloor(struct ar9170 *ar) 1557int carl9170_get_noisefloor(struct ar9170 *ar)
1567{ 1558{
1568 static const u32 phy_regs[] = { 1559 static const u32 phy_regs[] = {
@@ -1578,11 +1569,11 @@ int carl9170_get_noisefloor(struct ar9170 *ar)
1578 return err; 1569 return err;
1579 1570
1580 for (i = 0; i < 2; i++) { 1571 for (i = 0; i < 2; i++) {
1581 ar->noise[i] = carl9170_calc_noise_dbm( 1572 ar->noise[i] = sign_extend32(GET_VAL(
1582 (phy_res[i] >> 19) & 0x1ff); 1573 AR9170_PHY_CCA_MIN_PWR, phy_res[i]), 8);
1583 1574
1584 ar->noise[i + 2] = carl9170_calc_noise_dbm( 1575 ar->noise[i + 2] = sign_extend32(GET_VAL(
1585 (phy_res[i + 2] >> 23) & 0x1ff); 1576 AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8);
1586 } 1577 }
1587 1578
1588 return 0; 1579 return 0;
diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h
index 02c34eb4ebde..024fb42bc787 100644
--- a/drivers/net/wireless/ath/carl9170/phy.h
+++ b/drivers/net/wireless/ath/carl9170/phy.h
@@ -139,8 +139,8 @@
139#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 139#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
140 140
141#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064) 141#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064)
142#define AR9170_PHY_CCA_MINCCA_PWR 0x0ff80000 142#define AR9170_PHY_CCA_MIN_PWR 0x0ff80000
143#define AR9170_PHY_CCA_MINCCA_PWR_S 19 143#define AR9170_PHY_CCA_MIN_PWR_S 19
144#define AR9170_PHY_CCA_THRESH62 0x0007f000 144#define AR9170_PHY_CCA_THRESH62 0x0007f000
145#define AR9170_PHY_CCA_THRESH62_S 12 145#define AR9170_PHY_CCA_THRESH62_S 12
146 146
@@ -338,8 +338,8 @@
338#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9 338#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9
339#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000 339#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000
340#define AR9170_PHY_EXT_CCA_THRESH62_S 16 340#define AR9170_PHY_EXT_CCA_THRESH62_S 16
341#define AR9170_PHY_EXT_MINCCA_PWR 0xff800000 341#define AR9170_PHY_EXT_CCA_MIN_PWR 0xff800000
342#define AR9170_PHY_EXT_MINCCA_PWR_S 23 342#define AR9170_PHY_EXT_CCA_MIN_PWR_S 23
343 343
344#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0) 344#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0)
345#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f 345#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f
@@ -546,19 +546,19 @@
546#define AR9170_PHY_FORCE_XPA_CFG_S 0 546#define AR9170_PHY_FORCE_XPA_CFG_S 0
547 547
548#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064) 548#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064)
549#define AR9170_PHY_CH1_MINCCA_PWR 0x0ff80000 549#define AR9170_PHY_CH1_CCA_MIN_PWR 0x0ff80000
550#define AR9170_PHY_CH1_MINCCA_PWR_S 19 550#define AR9170_PHY_CH1_CCA_MIN_PWR_S 19
551 551
552#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064) 552#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064)
553#define AR9170_PHY_CH2_MINCCA_PWR 0x0ff80000 553#define AR9170_PHY_CH2_CCA_MIN_PWR 0x0ff80000
554#define AR9170_PHY_CH2_MINCCA_PWR_S 19 554#define AR9170_PHY_CH2_CCA_MIN_PWR_S 19
555 555
556#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc) 556#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc)
557#define AR9170_PHY_CH1_EXT_MINCCA_PWR 0xff800000 557#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR 0xff800000
558#define AR9170_PHY_CH1_EXT_MINCCA_PWR_S 23 558#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR_S 23
559 559
560#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc) 560#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc)
561#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000 561#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR 0xff800000
562#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23 562#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR_S 23
563 563
564#endif /* __CARL9170_SHARED_PHY_H */ 564#endif /* __CARL9170_SHARED_PHY_H */
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index b575c865142d..688eede48516 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -242,9 +242,11 @@ static void carl9170_tx_release(struct kref *ref)
242 ar->tx_ampdu_schedule = true; 242 ar->tx_ampdu_schedule = true;
243 243
244 if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) { 244 if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) {
245 txinfo->status.ampdu_len = txinfo->pad[0]; 245 struct _carl9170_tx_superframe *super;
246 txinfo->status.ampdu_ack_len = txinfo->pad[1]; 246
247 txinfo->pad[0] = txinfo->pad[1] = 0; 247 super = (void *)skb->data;
248 txinfo->status.ampdu_len = super->s.rix;
249 txinfo->status.ampdu_ack_len = super->s.cnt;
248 } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) { 250 } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) {
249 /* 251 /*
250 * drop redundant tx_status reports: 252 * drop redundant tx_status reports:
@@ -337,7 +339,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
337 u8 tid; 339 u8 tid;
338 340
339 if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || 341 if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
340 txinfo->flags & IEEE80211_TX_CTL_INJECTED) 342 txinfo->flags & IEEE80211_TX_CTL_INJECTED ||
343 (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
341 return; 344 return;
342 345
343 tx_info = IEEE80211_SKB_CB(skb); 346 tx_info = IEEE80211_SKB_CB(skb);
@@ -389,8 +392,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
389 sta_info->stats[tid].ampdu_ack_len++; 392 sta_info->stats[tid].ampdu_ack_len++;
390 393
391 if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) { 394 if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) {
392 txinfo->pad[0] = sta_info->stats[tid].ampdu_len; 395 super->s.rix = sta_info->stats[tid].ampdu_len;
393 txinfo->pad[1] = sta_info->stats[tid].ampdu_ack_len; 396 super->s.cnt = sta_info->stats[tid].ampdu_ack_len;
394 txinfo->flags |= IEEE80211_TX_STAT_AMPDU; 397 txinfo->flags |= IEEE80211_TX_STAT_AMPDU;
395 sta_info->stats[tid].clear = true; 398 sta_info->stats[tid].clear = true;
396 } 399 }
@@ -524,6 +527,59 @@ next:
524 } 527 }
525} 528}
526 529
530static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
531{
532 struct carl9170_sta_tid *iter;
533 struct sk_buff *skb;
534 struct ieee80211_tx_info *txinfo;
535 struct carl9170_tx_info *arinfo;
536 struct _carl9170_tx_superframe *super;
537 struct ieee80211_sta *sta;
538 struct ieee80211_vif *vif;
539 struct ieee80211_hdr *hdr;
540 unsigned int vif_id;
541
542 rcu_read_lock();
543 list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
544 if (iter->state < CARL9170_TID_STATE_IDLE)
545 continue;
546
547 spin_lock_bh(&iter->lock);
548 skb = skb_peek(&iter->queue);
549 if (!skb)
550 goto unlock;
551
552 txinfo = IEEE80211_SKB_CB(skb);
553 arinfo = (void *)txinfo->rate_driver_data;
554 if (time_is_after_jiffies(arinfo->timeout +
555 msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
556 goto unlock;
557
558 super = (void *) skb->data;
559 hdr = (void *) super->frame_data;
560
561 vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
562 CARL9170_TX_SUPER_MISC_VIF_ID_S;
563
564 if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
565 goto unlock;
566
567 vif = rcu_dereference(ar->vif_priv[vif_id].vif);
568 if (WARN_ON(!vif))
569 goto unlock;
570
571 sta = ieee80211_find_sta(vif, hdr->addr1);
572 if (WARN_ON(!sta))
573 goto unlock;
574
575 ieee80211_stop_tx_ba_session(sta, iter->tid);
576unlock:
577 spin_unlock_bh(&iter->lock);
578
579 }
580 rcu_read_unlock();
581}
582
527void carl9170_tx_janitor(struct work_struct *work) 583void carl9170_tx_janitor(struct work_struct *work)
528{ 584{
529 struct ar9170 *ar = container_of(work, struct ar9170, 585 struct ar9170 *ar = container_of(work, struct ar9170,
@@ -534,6 +590,7 @@ void carl9170_tx_janitor(struct work_struct *work)
534 ar->tx_janitor_last_run = jiffies; 590 ar->tx_janitor_last_run = jiffies;
535 591
536 carl9170_check_queue_stop_timeout(ar); 592 carl9170_check_queue_stop_timeout(ar);
593 carl9170_tx_ampdu_timeout(ar);
537 594
538 if (!atomic_read(&ar->tx_total_queued)) 595 if (!atomic_read(&ar->tx_total_queued))
539 return; 596 return;
@@ -842,10 +899,8 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
842 if (unlikely(!sta || !cvif)) 899 if (unlikely(!sta || !cvif))
843 goto err_out; 900 goto err_out;
844 901
845 factor = min_t(unsigned int, 1u, 902 factor = min_t(unsigned int, 1u, sta->ht_cap.ampdu_factor);
846 info->control.sta->ht_cap.ampdu_factor); 903 density = sta->ht_cap.ampdu_density;
847
848 density = info->control.sta->ht_cap.ampdu_density;
849 904
850 if (density) { 905 if (density) {
851 /* 906 /*
@@ -1206,6 +1261,7 @@ static void carl9170_tx(struct ar9170 *ar)
1206static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, 1261static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
1207 struct ieee80211_sta *sta, struct sk_buff *skb) 1262 struct ieee80211_sta *sta, struct sk_buff *skb)
1208{ 1263{
1264 struct _carl9170_tx_superframe *super = (void *) super;
1209 struct carl9170_sta_info *sta_info; 1265 struct carl9170_sta_info *sta_info;
1210 struct carl9170_sta_tid *agg; 1266 struct carl9170_sta_tid *agg;
1211 struct sk_buff *iter; 1267 struct sk_buff *iter;
@@ -1274,6 +1330,7 @@ err_unlock:
1274 1330
1275err_unlock_rcu: 1331err_unlock_rcu:
1276 rcu_read_unlock(); 1332 rcu_read_unlock();
1333 super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR);
1277 carl9170_tx_status(ar, skb, false); 1334 carl9170_tx_status(ar, skb, false);
1278 ar->tx_dropped++; 1335 ar->tx_dropped++;
1279 return false; 1336 return false;
@@ -1302,9 +1359,6 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1302 */ 1359 */
1303 1360
1304 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 1361 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1305 if (WARN_ON_ONCE(!sta))
1306 goto err_free;
1307
1308 run = carl9170_tx_ampdu_queue(ar, sta, skb); 1362 run = carl9170_tx_ampdu_queue(ar, sta, skb);
1309 if (run) 1363 if (run)
1310 carl9170_tx_ampdu(ar); 1364 carl9170_tx_ampdu(ar);
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 3317039cd28f..82c5f1c50650 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -433,7 +433,7 @@ static void carl9170_usb_rx_complete(struct urb *urb)
433 * device. 433 * device.
434 */ 434 */
435 435
436 carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM); 436 ieee80211_queue_work(ar->hw, &ar->ping_work);
437 } 437 }
438 } else { 438 } else {
439 /* 439 /*
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
index ff53f078a0b5..ee0f84f2a2f6 100644
--- a/drivers/net/wireless/ath/carl9170/version.h
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -1,7 +1,7 @@
1#ifndef __CARL9170_SHARED_VERSION_H 1#ifndef __CARL9170_SHARED_VERSION_H
2#define __CARL9170_SHARED_VERSION_H 2#define __CARL9170_SHARED_VERSION_H
3#define CARL9170FW_VERSION_YEAR 10 3#define CARL9170FW_VERSION_YEAR 10
4#define CARL9170FW_VERSION_MONTH 9 4#define CARL9170FW_VERSION_MONTH 10
5#define CARL9170FW_VERSION_DAY 28 5#define CARL9170FW_VERSION_DAY 29
6#define CARL9170FW_VERSION_GIT "1.8.8.3" 6#define CARL9170FW_VERSION_GIT "1.9.0"
7#endif /* __CARL9170_SHARED_VERSION_H */ 7#endif /* __CARL9170_SHARED_VERSION_H */