aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c119
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c64
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h19
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c27
17 files changed, 184 insertions, 188 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index f2eec388693b..73a8014cacb2 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -57,10 +57,11 @@
57#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 57#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
58#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 58#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
59 59
60#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
61
60static int ar9003_hw_power_interpolate(int32_t x, 62static int ar9003_hw_power_interpolate(int32_t x,
61 int32_t *px, int32_t *py, u_int16_t np); 63 int32_t *px, int32_t *py, u_int16_t np);
62 64
63#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
64 65
65static const struct ar9300_eeprom ar9300_default = { 66static const struct ar9300_eeprom ar9300_default = {
66 .eepromVersion = 2, 67 .eepromVersion = 2,
@@ -3032,6 +3033,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
3032 return le32_to_cpu(pBase->swreg); 3033 return le32_to_cpu(pBase->swreg);
3033 case EEP_PAPRD: 3034 case EEP_PAPRD:
3034 return !!(pBase->featureEnable & BIT(5)); 3035 return !!(pBase->featureEnable & BIT(5));
3036 case EEP_CHAIN_MASK_REDUCE:
3037 return (pBase->miscConfiguration >> 0x3) & 0x1;
3035 default: 3038 default:
3036 return 0; 3039 return 0;
3037 } 3040 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 656d8ce251a7..b34a9e91edd8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -487,7 +487,11 @@ void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
487 break; 487 break;
488 } 488 }
489 489
490 REG_WRITE(ah, AR_SELFGEN_MASK, tx); 490 if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
491 REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
492 else
493 REG_WRITE(ah, AR_SELFGEN_MASK, tx);
494
491 if (tx == 0x5) { 495 if (tx == 0x5) {
492 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, 496 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
493 AR_PHY_SWAP_ALT_CHAIN); 497 AR_PHY_SWAP_ALT_CHAIN);
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0b4b4704b1f0..4210a9306955 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -545,6 +545,7 @@ struct ath_ant_comb {
545#define SC_OP_BT_PRIORITY_DETECTED BIT(12) 545#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
546#define SC_OP_BT_SCAN BIT(13) 546#define SC_OP_BT_SCAN BIT(13)
547#define SC_OP_ANI_RUN BIT(14) 547#define SC_OP_ANI_RUN BIT(14)
548#define SC_OP_ENABLE_APM BIT(15)
548 549
549/* Powersave flags */ 550/* Powersave flags */
550#define PS_WAIT_FOR_BEACON BIT(0) 551#define PS_WAIT_FOR_BEACON BIT(0)
@@ -697,6 +698,8 @@ static inline void ath_ahb_exit(void) {};
697void ath9k_ps_wakeup(struct ath_softc *sc); 698void ath9k_ps_wakeup(struct ath_softc *sc);
698void ath9k_ps_restore(struct ath_softc *sc); 699void ath9k_ps_restore(struct ath_softc *sc);
699 700
701u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
702
700void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 703void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
701int ath9k_wiphy_add(struct ath_softc *sc); 704int ath9k_wiphy_add(struct ath_softc *sc);
702int ath9k_wiphy_del(struct ath_wiphy *aphy); 705int ath9k_wiphy_del(struct ath_wiphy *aphy);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 30724a4e8bb2..47bedd82e9a9 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -103,7 +103,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
103 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); 103 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
104 series[0].Tries = 1; 104 series[0].Tries = 1;
105 series[0].Rate = rate; 105 series[0].Rate = rate;
106 series[0].ChSel = common->tx_chainmask; 106 series[0].ChSel = ath_txchainmask_reduction(sc,
107 common->tx_chainmask, series[0].Rate);
107 series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0; 108 series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
108 ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration, 109 ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
109 series, 4, 0); 110 series, 4, 0);
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 6a92e57fddf0..d33bf204c995 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -35,29 +35,6 @@ struct ath_btcoex_config {
35 bool bt_hold_rx_clear; 35 bool bt_hold_rx_clear;
36}; 36};
37 37
38static const u16 ath_subsysid_tbl[] = {
39 AR9280_COEX2WIRE_SUBSYSID,
40 AT9285_COEX3WIRE_SA_SUBSYSID,
41 AT9285_COEX3WIRE_DA_SUBSYSID
42};
43
44/*
45 * Checks the subsystem id of the device to see if it
46 * supports btcoex
47 */
48bool ath9k_hw_btcoex_supported(struct ath_hw *ah)
49{
50 int i;
51
52 if (!ah->hw_version.subsysid)
53 return false;
54
55 for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++)
56 if (ah->hw_version.subsysid == ath_subsysid_tbl[i])
57 return true;
58
59 return false;
60}
61 38
62void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) 39void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
63{ 40{
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 1ee5a15ccbb1..588dfd464dd1 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -49,7 +49,6 @@ struct ath_btcoex_hw {
49 u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */ 49 u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */
50}; 50};
51 51
52bool ath9k_hw_btcoex_supported(struct ath_hw *ah);
53void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah); 52void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
54void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah); 53void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
55void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum); 54void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 0c3c74c157fb..3586c43077a7 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -24,8 +24,6 @@
24#define REG_READ_D(_ah, _reg) \ 24#define REG_READ_D(_ah, _reg) \
25 ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) 25 ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
26 26
27static struct dentry *ath9k_debugfs_root;
28
29static int ath9k_debugfs_open(struct inode *inode, struct file *file) 27static int ath9k_debugfs_open(struct inode *inode, struct file *file)
30{ 28{
31 file->private_data = inode->i_private; 29 file->private_data = inode->i_private;
@@ -878,11 +876,8 @@ int ath9k_init_debug(struct ath_hw *ah)
878 struct ath_common *common = ath9k_hw_common(ah); 876 struct ath_common *common = ath9k_hw_common(ah);
879 struct ath_softc *sc = (struct ath_softc *) common->priv; 877 struct ath_softc *sc = (struct ath_softc *) common->priv;
880 878
881 if (!ath9k_debugfs_root) 879 sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
882 return -ENOENT; 880 sc->hw->wiphy->debugfsdir);
883
884 sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
885 ath9k_debugfs_root);
886 if (!sc->debug.debugfs_phy) 881 if (!sc->debug.debugfs_phy)
887 return -ENOMEM; 882 return -ENOMEM;
888 883
@@ -935,29 +930,7 @@ int ath9k_init_debug(struct ath_hw *ah)
935 sc->debug.regidx = 0; 930 sc->debug.regidx = 0;
936 return 0; 931 return 0;
937err: 932err:
938 ath9k_exit_debug(ah);
939 return -ENOMEM;
940}
941
942void ath9k_exit_debug(struct ath_hw *ah)
943{
944 struct ath_common *common = ath9k_hw_common(ah);
945 struct ath_softc *sc = (struct ath_softc *) common->priv;
946
947 debugfs_remove_recursive(sc->debug.debugfs_phy); 933 debugfs_remove_recursive(sc->debug.debugfs_phy);
948} 934 sc->debug.debugfs_phy = NULL;
949 935 return -ENOMEM;
950int ath9k_debug_create_root(void)
951{
952 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
953 if (!ath9k_debugfs_root)
954 return -ENOENT;
955
956 return 0;
957}
958
959void ath9k_debug_remove_root(void)
960{
961 debugfs_remove(ath9k_debugfs_root);
962 ath9k_debugfs_root = NULL;
963} 936}
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 646ff7e04c88..1e5078bd0344 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -164,10 +164,7 @@ struct ath9k_debug {
164}; 164};
165 165
166int ath9k_init_debug(struct ath_hw *ah); 166int ath9k_init_debug(struct ath_hw *ah);
167void ath9k_exit_debug(struct ath_hw *ah);
168 167
169int ath9k_debug_create_root(void);
170void ath9k_debug_remove_root(void);
171void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 168void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
172void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, 169void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
173 struct ath_tx_status *ts); 170 struct ath_tx_status *ts);
@@ -180,19 +177,6 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
180 return 0; 177 return 0;
181} 178}
182 179
183static inline void ath9k_exit_debug(struct ath_hw *ah)
184{
185}
186
187static inline int ath9k_debug_create_root(void)
188{
189 return 0;
190}
191
192static inline void ath9k_debug_remove_root(void)
193{
194}
195
196static inline void ath_debug_stat_interrupt(struct ath_softc *sc, 180static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
197 enum ath9k_int status) 181 enum ath9k_int status)
198{ 182{
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 8a644fced5c9..8b9885b5243f 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -280,6 +280,7 @@ enum eeprom_param {
280 EEP_PAPRD, 280 EEP_PAPRD,
281 EEP_MODAL_VER, 281 EEP_MODAL_VER,
282 EEP_ANT_DIV_CTL1, 282 EEP_ANT_DIV_CTL1,
283 EEP_CHAIN_MASK_REDUCE
283}; 284};
284 285
285enum ar5416_rates { 286enum ar5416_rates {
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index ae842dbf9b50..8946e8ad1b85 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -363,9 +363,9 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
363 struct sk_buff *skb) 363 struct sk_buff *skb)
364{ 364{
365 struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER]; 365 struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER];
366 int index = 0, i = 0, chk_idx, len = skb->len; 366 int index = 0, i = 0, len = skb->len;
367 int rx_remain_len = 0, rx_pkt_len = 0; 367 int rx_remain_len, rx_pkt_len;
368 u16 pkt_len, pkt_tag, pool_index = 0; 368 u16 pool_index = 0;
369 u8 *ptr; 369 u8 *ptr;
370 370
371 spin_lock(&hif_dev->rx_lock); 371 spin_lock(&hif_dev->rx_lock);
@@ -399,64 +399,64 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
399 spin_unlock(&hif_dev->rx_lock); 399 spin_unlock(&hif_dev->rx_lock);
400 400
401 while (index < len) { 401 while (index < len) {
402 u16 pkt_len;
403 u16 pkt_tag;
404 u16 pad_len;
405 int chk_idx;
406
402 ptr = (u8 *) skb->data; 407 ptr = (u8 *) skb->data;
403 408
404 pkt_len = ptr[index] + (ptr[index+1] << 8); 409 pkt_len = ptr[index] + (ptr[index+1] << 8);
405 pkt_tag = ptr[index+2] + (ptr[index+3] << 8); 410 pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
406 411
407 if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) { 412 if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
408 u16 pad_len; 413 RX_STAT_INC(skb_dropped);
409 414 return;
410 pad_len = 4 - (pkt_len & 0x3); 415 }
411 if (pad_len == 4) 416
412 pad_len = 0; 417 pad_len = 4 - (pkt_len & 0x3);
413 418 if (pad_len == 4)
414 chk_idx = index; 419 pad_len = 0;
415 index = index + 4 + pkt_len + pad_len; 420
416 421 chk_idx = index;
417 if (index > MAX_RX_BUF_SIZE) { 422 index = index + 4 + pkt_len + pad_len;
418 spin_lock(&hif_dev->rx_lock); 423
419 hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE; 424 if (index > MAX_RX_BUF_SIZE) {
420 hif_dev->rx_transfer_len = 425 spin_lock(&hif_dev->rx_lock);
421 MAX_RX_BUF_SIZE - chk_idx - 4; 426 hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
422 hif_dev->rx_pad_len = pad_len; 427 hif_dev->rx_transfer_len =
423 428 MAX_RX_BUF_SIZE - chk_idx - 4;
424 nskb = __dev_alloc_skb(pkt_len + 32, 429 hif_dev->rx_pad_len = pad_len;
425 GFP_ATOMIC); 430
426 if (!nskb) { 431 nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
427 dev_err(&hif_dev->udev->dev, 432 if (!nskb) {
428 "ath9k_htc: RX memory allocation" 433 dev_err(&hif_dev->udev->dev,
429 " error\n"); 434 "ath9k_htc: RX memory allocation error\n");
430 spin_unlock(&hif_dev->rx_lock);
431 goto err;
432 }
433 skb_reserve(nskb, 32);
434 RX_STAT_INC(skb_allocated);
435
436 memcpy(nskb->data, &(skb->data[chk_idx+4]),
437 hif_dev->rx_transfer_len);
438
439 /* Record the buffer pointer */
440 hif_dev->remain_skb = nskb;
441 spin_unlock(&hif_dev->rx_lock); 435 spin_unlock(&hif_dev->rx_lock);
442 } else { 436 goto err;
443 nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
444 if (!nskb) {
445 dev_err(&hif_dev->udev->dev,
446 "ath9k_htc: RX memory allocation"
447 " error\n");
448 goto err;
449 }
450 skb_reserve(nskb, 32);
451 RX_STAT_INC(skb_allocated);
452
453 memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
454 skb_put(nskb, pkt_len);
455 skb_pool[pool_index++] = nskb;
456 } 437 }
438 skb_reserve(nskb, 32);
439 RX_STAT_INC(skb_allocated);
440
441 memcpy(nskb->data, &(skb->data[chk_idx+4]),
442 hif_dev->rx_transfer_len);
443
444 /* Record the buffer pointer */
445 hif_dev->remain_skb = nskb;
446 spin_unlock(&hif_dev->rx_lock);
457 } else { 447 } else {
458 RX_STAT_INC(skb_dropped); 448 nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
459 return; 449 if (!nskb) {
450 dev_err(&hif_dev->udev->dev,
451 "ath9k_htc: RX memory allocation error\n");
452 goto err;
453 }
454 skb_reserve(nskb, 32);
455 RX_STAT_INC(skb_allocated);
456
457 memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
458 skb_put(nskb, pkt_len);
459 skb_pool[pool_index++] = nskb;
460 } 460 }
461 } 461 }
462 462
@@ -471,7 +471,7 @@ err:
471static void ath9k_hif_usb_rx_cb(struct urb *urb) 471static void ath9k_hif_usb_rx_cb(struct urb *urb)
472{ 472{
473 struct sk_buff *skb = (struct sk_buff *) urb->context; 473 struct sk_buff *skb = (struct sk_buff *) urb->context;
474 struct hif_device_usb *hif_dev = (struct hif_device_usb *) 474 struct hif_device_usb *hif_dev =
475 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); 475 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
476 int ret; 476 int ret;
477 477
@@ -518,7 +518,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
518{ 518{
519 struct sk_buff *skb = (struct sk_buff *) urb->context; 519 struct sk_buff *skb = (struct sk_buff *) urb->context;
520 struct sk_buff *nskb; 520 struct sk_buff *nskb;
521 struct hif_device_usb *hif_dev = (struct hif_device_usb *) 521 struct hif_device_usb *hif_dev =
522 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); 522 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
523 int ret; 523 int ret;
524 524
@@ -993,8 +993,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev)
993static void ath9k_hif_usb_disconnect(struct usb_interface *interface) 993static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
994{ 994{
995 struct usb_device *udev = interface_to_usbdev(interface); 995 struct usb_device *udev = interface_to_usbdev(interface);
996 struct hif_device_usb *hif_dev = 996 struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
997 (struct hif_device_usb *) usb_get_intfdata(interface);
998 997
999 if (hif_dev) { 998 if (hif_dev) {
1000 ath9k_htc_hw_deinit(hif_dev->htc_handle, 999 ath9k_htc_hw_deinit(hif_dev->htc_handle,
@@ -1016,8 +1015,7 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
1016static int ath9k_hif_usb_suspend(struct usb_interface *interface, 1015static int ath9k_hif_usb_suspend(struct usb_interface *interface,
1017 pm_message_t message) 1016 pm_message_t message)
1018{ 1017{
1019 struct hif_device_usb *hif_dev = 1018 struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
1020 (struct hif_device_usb *) usb_get_intfdata(interface);
1021 1019
1022 ath9k_hif_usb_dealloc_urbs(hif_dev); 1020 ath9k_hif_usb_dealloc_urbs(hif_dev);
1023 1021
@@ -1026,8 +1024,7 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface,
1026 1024
1027static int ath9k_hif_usb_resume(struct usb_interface *interface) 1025static int ath9k_hif_usb_resume(struct usb_interface *interface)
1028{ 1026{
1029 struct hif_device_usb *hif_dev = 1027 struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
1030 (struct hif_device_usb *) usb_get_intfdata(interface);
1031 struct htc_target *htc_handle = hif_dev->htc_handle; 1028 struct htc_target *htc_handle = hif_dev->htc_handle;
1032 int ret; 1029 int ret;
1033 1030
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index e9761c2c8700..8266ce1f02e3 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -184,6 +184,47 @@ err:
184 return ret; 184 return ret;
185} 185}
186 186
187static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
188{
189 struct ath_common *common = ath9k_hw_common(priv->ah);
190 struct ath9k_htc_target_vif hvif;
191 int ret = 0;
192 u8 cmd_rsp;
193
194 if (priv->nvifs > 0)
195 return -ENOBUFS;
196
197 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
198 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
199
200 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
201 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
202 hvif.index = priv->nvifs;
203
204 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
205 if (ret)
206 return ret;
207
208 priv->nvifs++;
209 return 0;
210}
211
212static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
213{
214 struct ath_common *common = ath9k_hw_common(priv->ah);
215 struct ath9k_htc_target_vif hvif;
216 int ret = 0;
217 u8 cmd_rsp;
218
219 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
220 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
221 hvif.index = 0; /* Should do for now */
222 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
223 priv->nvifs--;
224
225 return ret;
226}
227
187static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, 228static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
188 struct ieee80211_vif *vif, 229 struct ieee80211_vif *vif,
189 struct ieee80211_sta *sta) 230 struct ieee80211_sta *sta)
@@ -1199,6 +1240,16 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1199 WMI_CMD(WMI_STOP_RECV_CMDID); 1240 WMI_CMD(WMI_STOP_RECV_CMDID);
1200 skb_queue_purge(&priv->tx_queue); 1241 skb_queue_purge(&priv->tx_queue);
1201 1242
1243 /* Remove monitor interface here */
1244 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1245 if (ath9k_htc_remove_monitor_interface(priv))
1246 ath_print(common, ATH_DBG_FATAL,
1247 "Unable to remove monitor interface\n");
1248 else
1249 ath_print(common, ATH_DBG_CONFIG,
1250 "Monitor interface removed\n");
1251 }
1252
1202 if (ah->btcoex_hw.enabled) { 1253 if (ah->btcoex_hw.enabled) {
1203 ath9k_hw_btcoex_disable(ah); 1254 ath9k_hw_btcoex_disable(ah);
1204 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 1255 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
@@ -1372,13 +1423,16 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1372 } 1423 }
1373 } 1424 }
1374 1425
1375 if (changed & IEEE80211_CONF_CHANGE_MONITOR) 1426 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1376 if (conf->flags & IEEE80211_CONF_MONITOR) { 1427 if (conf->flags & IEEE80211_CONF_MONITOR) {
1377 ath_print(common, ATH_DBG_CONFIG, 1428 if (ath9k_htc_add_monitor_interface(priv))
1378 "HW opmode set to Monitor mode\n"); 1429 ath_print(common, ATH_DBG_FATAL,
1379 priv->ah->opmode = NL80211_IFTYPE_MONITOR; 1430 "Failed to set monitor mode\n");
1431 else
1432 ath_print(common, ATH_DBG_CONFIG,
1433 "HW opmode set to Monitor mode\n");
1380 } 1434 }
1381 1435 }
1382 1436
1383 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 1437 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1384 mutex_lock(&priv->htc_pm_lock); 1438 mutex_lock(&priv->htc_pm_lock);
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index 6fc1b21faa5d..ecd018798c47 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -77,20 +77,6 @@ struct htc_config_pipe_msg {
77 u8 credits; 77 u8 credits;
78} __packed; 78} __packed;
79 79
80struct htc_packet {
81 void *pktcontext;
82 u8 *buf;
83 u8 *buf_payload;
84 u32 buflen;
85 u32 payload_len;
86
87 int endpoint;
88 int status;
89
90 void *context;
91 u32 reserved;
92};
93
94struct htc_ep_callbacks { 80struct htc_ep_callbacks {
95 void *priv; 81 void *priv;
96 void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok); 82 void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
@@ -123,11 +109,6 @@ struct htc_endpoint {
123#define HTC_CONTROL_BUFFER_SIZE \ 109#define HTC_CONTROL_BUFFER_SIZE \
124 (HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr)) 110 (HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
125 111
126struct htc_control_buf {
127 struct htc_packet htc_pkt;
128 u8 buf[HTC_CONTROL_BUFFER_SIZE];
129};
130
131#define HTC_OP_START_WAIT BIT(0) 112#define HTC_OP_START_WAIT BIT(0)
132#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1) 113#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1)
133 114
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 380d0c651137..9b1ee7fc05c1 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1925,8 +1925,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
1925 pCap->num_antcfg_2ghz = 1925 pCap->num_antcfg_2ghz =
1926 ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); 1926 ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
1927 1927
1928 if (AR_SREV_9280_20_OR_LATER(ah) && 1928 if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
1929 ath9k_hw_btcoex_supported(ah)) {
1930 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; 1929 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
1931 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; 1930 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
1932 1931
@@ -1975,6 +1974,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
1975 if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1)) 1974 if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1))
1976 pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; 1975 pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
1977 } 1976 }
1977 if (AR_SREV_9300_20_OR_LATER(ah)) {
1978 if (ah->eep_ops->get_eeprom(ah, EEP_CHAIN_MASK_REDUCE))
1979 pCap->hw_caps |= ATH9K_HW_CAP_APM;
1980 }
1981
1982
1978 1983
1979 return 0; 1984 return 0;
1980} 1985}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index cc8f3b9af71f..5fcfa48a45df 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -187,6 +187,7 @@ enum ath9k_hw_caps {
187 ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12), 187 ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12),
188 ATH9K_HW_CAP_2GHZ = BIT(13), 188 ATH9K_HW_CAP_2GHZ = BIT(13),
189 ATH9K_HW_CAP_5GHZ = BIT(14), 189 ATH9K_HW_CAP_5GHZ = BIT(14),
190 ATH9K_HW_CAP_APM = BIT(15),
190}; 191};
191 192
192struct ath9k_hw_capabilities { 193struct ath9k_hw_capabilities {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 84e19e504dd0..918308a28410 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -37,6 +37,10 @@ int led_blink;
37module_param_named(blink, led_blink, int, 0444); 37module_param_named(blink, led_blink, int, 0444);
38MODULE_PARM_DESC(blink, "Enable LED blink on activity"); 38MODULE_PARM_DESC(blink, "Enable LED blink on activity");
39 39
40static int ath9k_btcoex_enable;
41module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
42MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
43
40/* We use the hw_value as an index into our private channel structure */ 44/* We use the hw_value as an index into our private channel structure */
41 45
42#define CHAN2G(_freq, _idx) { \ 46#define CHAN2G(_freq, _idx) { \
@@ -540,6 +544,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
540 common->hw = sc->hw; 544 common->hw = sc->hw;
541 common->priv = sc; 545 common->priv = sc;
542 common->debug_mask = ath9k_debug; 546 common->debug_mask = ath9k_debug;
547 common->btcoex_enabled = ath9k_btcoex_enable == 1;
543 spin_lock_init(&common->cc_lock); 548 spin_lock_init(&common->cc_lock);
544 549
545 spin_lock_init(&sc->wiphy_lock); 550 spin_lock_init(&sc->wiphy_lock);
@@ -562,13 +567,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
562 if (ret) 567 if (ret)
563 goto err_hw; 568 goto err_hw;
564 569
565 ret = ath9k_init_debug(ah);
566 if (ret) {
567 ath_print(common, ATH_DBG_FATAL,
568 "Unable to create debugfs files\n");
569 goto err_debug;
570 }
571
572 ret = ath9k_init_queues(sc); 570 ret = ath9k_init_queues(sc);
573 if (ret) 571 if (ret)
574 goto err_queues; 572 goto err_queues;
@@ -591,8 +589,6 @@ err_btcoex:
591 if (ATH_TXQ_SETUP(sc, i)) 589 if (ATH_TXQ_SETUP(sc, i))
592 ath_tx_cleanupq(sc, &sc->tx.txq[i]); 590 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
593err_queues: 591err_queues:
594 ath9k_exit_debug(ah);
595err_debug:
596 ath9k_hw_deinit(ah); 592 ath9k_hw_deinit(ah);
597err_hw: 593err_hw:
598 tasklet_kill(&sc->intr_tq); 594 tasklet_kill(&sc->intr_tq);
@@ -738,6 +734,13 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
738 if (error) 734 if (error)
739 goto error_register; 735 goto error_register;
740 736
737 error = ath9k_init_debug(ah);
738 if (error) {
739 ath_print(common, ATH_DBG_FATAL,
740 "Unable to create debugfs files\n");
741 goto error_world;
742 }
743
741 /* Handle world regulatory */ 744 /* Handle world regulatory */
742 if (!ath_is_world_regd(reg)) { 745 if (!ath_is_world_regd(reg)) {
743 error = regulatory_hint(hw->wiphy, reg->alpha2); 746 error = regulatory_hint(hw->wiphy, reg->alpha2);
@@ -796,7 +799,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
796 if (ATH_TXQ_SETUP(sc, i)) 799 if (ATH_TXQ_SETUP(sc, i))
797 ath_tx_cleanupq(sc, &sc->tx.txq[i]); 800 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
798 801
799 ath9k_exit_debug(sc->sc_ah);
800 ath9k_hw_deinit(sc->sc_ah); 802 ath9k_hw_deinit(sc->sc_ah);
801 803
802 tasklet_kill(&sc->intr_tq); 804 tasklet_kill(&sc->intr_tq);
@@ -863,20 +865,12 @@ static int __init ath9k_init(void)
863 goto err_out; 865 goto err_out;
864 } 866 }
865 867
866 error = ath9k_debug_create_root();
867 if (error) {
868 printk(KERN_ERR
869 "ath9k: Unable to create debugfs root: %d\n",
870 error);
871 goto err_rate_unregister;
872 }
873
874 error = ath_pci_init(); 868 error = ath_pci_init();
875 if (error < 0) { 869 if (error < 0) {
876 printk(KERN_ERR 870 printk(KERN_ERR
877 "ath9k: No PCI devices found, driver not installed.\n"); 871 "ath9k: No PCI devices found, driver not installed.\n");
878 error = -ENODEV; 872 error = -ENODEV;
879 goto err_remove_root; 873 goto err_rate_unregister;
880 } 874 }
881 875
882 error = ath_ahb_init(); 876 error = ath_ahb_init();
@@ -890,8 +884,6 @@ static int __init ath9k_init(void)
890 err_pci_exit: 884 err_pci_exit:
891 ath_pci_exit(); 885 ath_pci_exit();
892 886
893 err_remove_root:
894 ath9k_debug_remove_root();
895 err_rate_unregister: 887 err_rate_unregister:
896 ath_rate_control_unregister(); 888 ath_rate_control_unregister();
897 err_out: 889 err_out:
@@ -903,7 +895,6 @@ static void __exit ath9k_exit(void)
903{ 895{
904 ath_ahb_exit(); 896 ath_ahb_exit();
905 ath_pci_exit(); 897 ath_pci_exit();
906 ath9k_debug_remove_root();
907 ath_rate_control_unregister(); 898 ath_rate_control_unregister();
908 printk(KERN_INFO "%s: Driver unloaded\n", dev_info); 899 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
909} 900}
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 7acd6b0ca011..f026a031713b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -553,9 +553,12 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
553static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) 553static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
554{ 554{
555 struct ath_node *an; 555 struct ath_node *an;
556 556 struct ath_hw *ah = sc->sc_ah;
557 an = (struct ath_node *)sta->drv_priv; 557 an = (struct ath_node *)sta->drv_priv;
558 558
559 if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM)
560 sc->sc_flags |= SC_OP_ENABLE_APM;
561
559 if (sc->sc_flags & SC_OP_TXAGGR) { 562 if (sc->sc_flags & SC_OP_TXAGGR) {
560 ath_tx_node_init(sc, an); 563 ath_tx_node_init(sc, an);
561 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + 564 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 495432ec85a9..821d3679c6ff 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -250,11 +250,11 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
250static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, 250static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
251 struct sk_buff *skb) 251 struct sk_buff *skb)
252{ 252{
253 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 253 struct ath_frame_info *fi = get_frame_info(skb);
254 struct ieee80211_hdr *hdr; 254 struct ieee80211_hdr *hdr;
255 255
256 TX_STAT_INC(txq->axq_qnum, a_retries); 256 TX_STAT_INC(txq->axq_qnum, a_retries);
257 if (tx_info->control.rates[4].count++ > 0) 257 if (fi->retries++ > 0)
258 return; 258 return;
259 259
260 hdr = (struct ieee80211_hdr *)skb->data; 260 hdr = (struct ieee80211_hdr *)skb->data;
@@ -1506,6 +1506,18 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
1506 return duration; 1506 return duration;
1507} 1507}
1508 1508
1509u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
1510{
1511 struct ath_hw *ah = sc->sc_ah;
1512 struct ath9k_channel *curchan = ah->curchan;
1513 if ((sc->sc_flags & SC_OP_ENABLE_APM) &&
1514 (curchan->channelFlags & CHANNEL_5GHZ) &&
1515 (chainmask == 0x7) && (rate < 0x90))
1516 return 0x3;
1517 else
1518 return chainmask;
1519}
1520
1509static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) 1521static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
1510{ 1522{
1511 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1523 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1546,7 +1558,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
1546 1558
1547 rix = rates[i].idx; 1559 rix = rates[i].idx;
1548 series[i].Tries = rates[i].count; 1560 series[i].Tries = rates[i].count;
1549 series[i].ChSel = common->tx_chainmask;
1550 1561
1551 if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) || 1562 if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
1552 (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) { 1563 (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
@@ -1569,6 +1580,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
1569 if (rates[i].flags & IEEE80211_TX_RC_MCS) { 1580 if (rates[i].flags & IEEE80211_TX_RC_MCS) {
1570 /* MCS rates */ 1581 /* MCS rates */
1571 series[i].Rate = rix | 0x80; 1582 series[i].Rate = rix | 0x80;
1583 series[i].ChSel = ath_txchainmask_reduction(sc,
1584 common->tx_chainmask, series[i].Rate);
1572 series[i].PktDuration = ath_pkt_duration(sc, rix, len, 1585 series[i].PktDuration = ath_pkt_duration(sc, rix, len,
1573 is_40, is_sgi, is_sp); 1586 is_40, is_sgi, is_sp);
1574 if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) 1587 if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
@@ -1576,7 +1589,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
1576 continue; 1589 continue;
1577 } 1590 }
1578 1591
1579 /* legcay rates */ 1592 /* legacy rates */
1580 if ((tx_info->band == IEEE80211_BAND_2GHZ) && 1593 if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
1581 !(rate->flags & IEEE80211_RATE_ERP_G)) 1594 !(rate->flags & IEEE80211_RATE_ERP_G))
1582 phy = WLAN_RC_PHY_CCK; 1595 phy = WLAN_RC_PHY_CCK;
@@ -1592,6 +1605,12 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
1592 is_sp = false; 1605 is_sp = false;
1593 } 1606 }
1594 1607
1608 if (bf->bf_state.bfs_paprd)
1609 series[i].ChSel = common->tx_chainmask;
1610 else
1611 series[i].ChSel = ath_txchainmask_reduction(sc,
1612 common->tx_chainmask, series[i].Rate);
1613
1595 series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, 1614 series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
1596 phy, rate->bitrate * 100, len, rix, is_sp); 1615 phy, rate->bitrate * 100, len, rix, is_sp);
1597 } 1616 }