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.h10
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.h4
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/fwdesc.h3
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h41
-rw-r--r--drivers/net/wireless/ath/carl9170/led.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c129
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c6
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c290
10 files changed, 277 insertions, 212 deletions
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index f9a4655ea0b8..c5427a72a1e2 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -177,7 +177,7 @@ struct carl9170_tx_queue_stats {
177 177
178struct carl9170_vif { 178struct carl9170_vif {
179 unsigned int id; 179 unsigned int id;
180 struct ieee80211_vif *vif; 180 struct ieee80211_vif __rcu *vif;
181}; 181};
182 182
183struct carl9170_vif_info { 183struct carl9170_vif_info {
@@ -311,7 +311,7 @@ struct ar9170 {
311 spinlock_t beacon_lock; 311 spinlock_t beacon_lock;
312 unsigned int global_pretbtt; 312 unsigned int global_pretbtt;
313 unsigned int global_beacon_int; 313 unsigned int global_beacon_int;
314 struct carl9170_vif_info *beacon_iter; 314 struct carl9170_vif_info __rcu *beacon_iter;
315 unsigned int beacon_enabled; 315 unsigned int beacon_enabled;
316 316
317 /* cryptographic engine */ 317 /* cryptographic engine */
@@ -389,7 +389,7 @@ struct ar9170 {
389 /* tx ampdu */ 389 /* tx ampdu */
390 struct work_struct ampdu_work; 390 struct work_struct ampdu_work;
391 spinlock_t tx_ampdu_list_lock; 391 spinlock_t tx_ampdu_list_lock;
392 struct carl9170_sta_tid *tx_ampdu_iter; 392 struct carl9170_sta_tid __rcu *tx_ampdu_iter;
393 struct list_head tx_ampdu_list; 393 struct list_head tx_ampdu_list;
394 atomic_t tx_ampdu_upload; 394 atomic_t tx_ampdu_upload;
395 atomic_t tx_ampdu_scheduler; 395 atomic_t tx_ampdu_scheduler;
@@ -456,7 +456,7 @@ struct carl9170_sta_info {
456 bool sleeping; 456 bool sleeping;
457 atomic_t pending_frames; 457 atomic_t pending_frames;
458 unsigned int ampdu_max_len; 458 unsigned int ampdu_max_len;
459 struct carl9170_sta_tid *agg[CARL9170_NUM_TID]; 459 struct carl9170_sta_tid __rcu *agg[CARL9170_NUM_TID];
460 struct carl9170_ba_stats stats[CARL9170_NUM_TID]; 460 struct carl9170_ba_stats stats[CARL9170_NUM_TID];
461}; 461};
462 462
@@ -532,7 +532,6 @@ int carl9170_set_ampdu_settings(struct ar9170 *ar);
532int carl9170_set_slot_time(struct ar9170 *ar); 532int carl9170_set_slot_time(struct ar9170 *ar);
533int carl9170_set_mac_rates(struct ar9170 *ar); 533int carl9170_set_mac_rates(struct ar9170 *ar);
534int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); 534int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry);
535int carl9170_update_beacon(struct ar9170 *ar, const bool submit);
536int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, 535int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
537 const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); 536 const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen);
538int carl9170_disable_key(struct ar9170 *ar, const u8 id); 537int carl9170_disable_key(struct ar9170 *ar, const u8 id);
@@ -553,6 +552,7 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb);
553void carl9170_tx_scheduler(struct ar9170 *ar); 552void carl9170_tx_scheduler(struct ar9170 *ar);
554void carl9170_tx_get_skb(struct sk_buff *skb); 553void carl9170_tx_get_skb(struct sk_buff *skb);
555int carl9170_tx_put_skb(struct sk_buff *skb); 554int carl9170_tx_put_skb(struct sk_buff *skb);
555int carl9170_update_beacon(struct ar9170 *ar, const bool submit);
556 556
557/* LEDs */ 557/* LEDs */
558#ifdef CONFIG_CARL9170_LEDS 558#ifdef CONFIG_CARL9170_LEDS
diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h
index 568174c71b94..d5f95bdc75c1 100644
--- a/drivers/net/wireless/ath/carl9170/cmd.h
+++ b/drivers/net/wireless/ath/carl9170/cmd.h
@@ -87,7 +87,7 @@ do { \
87 __ar->cmd_buf[2 * __nreg + 1] = cpu_to_le32(r); \ 87 __ar->cmd_buf[2 * __nreg + 1] = cpu_to_le32(r); \
88 __ar->cmd_buf[2 * __nreg + 2] = cpu_to_le32(v); \ 88 __ar->cmd_buf[2 * __nreg + 2] = cpu_to_le32(v); \
89 __nreg++; \ 89 __nreg++; \
90 if ((__nreg >= PAYLOAD_MAX/2)) { \ 90 if ((__nreg >= PAYLOAD_MAX / 2)) { \
91 if (IS_ACCEPTING_CMD(__ar)) \ 91 if (IS_ACCEPTING_CMD(__ar)) \
92 __err = carl9170_exec_cmd(__ar, \ 92 __err = carl9170_exec_cmd(__ar, \
93 CARL9170_CMD_WREG, 8 * __nreg, \ 93 CARL9170_CMD_WREG, 8 * __nreg, \
@@ -160,7 +160,7 @@ do { \
160} while (0) 160} while (0)
161 161
162#define carl9170_async_regwrite_finish() do { \ 162#define carl9170_async_regwrite_finish() do { \
163__async_regwrite_out : \ 163__async_regwrite_out: \
164 if (__cmd != NULL && __err == 0) \ 164 if (__cmd != NULL && __err == 0) \
165 carl9170_async_regwrite_flush(); \ 165 carl9170_async_regwrite_flush(); \
166 kfree(__cmd); \ 166 kfree(__cmd); \
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
index 0ac1124c2a0b..de57f90e1d5f 100644
--- a/drivers/net/wireless/ath/carl9170/debug.c
+++ b/drivers/net/wireless/ath/carl9170/debug.c
@@ -695,7 +695,7 @@ static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf,
695} 695}
696__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED); 696__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED);
697 697
698static const char *erp_modes[] = { 698static const char *const erp_modes[] = {
699 [CARL9170_ERP_INVALID] = "INVALID", 699 [CARL9170_ERP_INVALID] = "INVALID",
700 [CARL9170_ERP_AUTO] = "Automatic", 700 [CARL9170_ERP_AUTO] = "Automatic",
701 [CARL9170_ERP_MAC80211] = "Set by MAC80211", 701 [CARL9170_ERP_MAC80211] = "Set by MAC80211",
diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h
index 7ba62bb77054..6d9c0891ce7f 100644
--- a/drivers/net/wireless/ath/carl9170/fwdesc.h
+++ b/drivers/net/wireless/ath/carl9170/fwdesc.h
@@ -75,6 +75,9 @@ enum carl9170fw_feature_list {
75 /* Firmware supports PSM in the 5GHZ Band */ 75 /* Firmware supports PSM in the 5GHZ Band */
76 CARL9170FW_FIXED_5GHZ_PSM, 76 CARL9170FW_FIXED_5GHZ_PSM,
77 77
78 /* HW (ANI, CCA, MIB) tally counters */
79 CARL9170FW_HW_COUNTERS,
80
78 /* KEEP LAST */ 81 /* KEEP LAST */
79 __CARL9170FW_FEATURE_NUM 82 __CARL9170FW_FEATURE_NUM
80}; 83};
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
index 261f89351070..fa834c1460f0 100644
--- a/drivers/net/wireless/ath/carl9170/hw.h
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -174,6 +174,7 @@
174#define AR9170_MAC_SNIFFER_ENABLE_PROMISC BIT(0) 174#define AR9170_MAC_SNIFFER_ENABLE_PROMISC BIT(0)
175#define AR9170_MAC_SNIFFER_DEFAULTS 0x02000000 175#define AR9170_MAC_SNIFFER_DEFAULTS 0x02000000
176#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678) 176#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678)
177#define AR9170_MAC_ENCRYPTION_MGMT_RX_SOFTWARE BIT(2)
177#define AR9170_MAC_ENCRYPTION_RX_SOFTWARE BIT(3) 178#define AR9170_MAC_ENCRYPTION_RX_SOFTWARE BIT(3)
178#define AR9170_MAC_ENCRYPTION_DEFAULTS 0x70 179#define AR9170_MAC_ENCRYPTION_DEFAULTS 0x70
179 180
@@ -222,6 +223,12 @@
222#define AR9170_MAC_REG_TX_BLOCKACKS (AR9170_MAC_REG_BASE + 0x6c0) 223#define AR9170_MAC_REG_TX_BLOCKACKS (AR9170_MAC_REG_BASE + 0x6c0)
223#define AR9170_MAC_REG_NAV_COUNT (AR9170_MAC_REG_BASE + 0x6c4) 224#define AR9170_MAC_REG_NAV_COUNT (AR9170_MAC_REG_BASE + 0x6c4)
224#define AR9170_MAC_REG_BACKOFF_STATUS (AR9170_MAC_REG_BASE + 0x6c8) 225#define AR9170_MAC_REG_BACKOFF_STATUS (AR9170_MAC_REG_BASE + 0x6c8)
226#define AR9170_MAC_BACKOFF_CCA BIT(24)
227#define AR9170_MAC_BACKOFF_TX_PEX BIT(25)
228#define AR9170_MAC_BACKOFF_RX_PE BIT(26)
229#define AR9170_MAC_BACKOFF_MD_READY BIT(27)
230#define AR9170_MAC_BACKOFF_TX_PE BIT(28)
231
225#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6cc) 232#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6cc)
226 233
227#define AR9170_MAC_REG_TX_COMPLETE (AR9170_MAC_REG_BASE + 0x6d4) 234#define AR9170_MAC_REG_TX_COMPLETE (AR9170_MAC_REG_BASE + 0x6d4)
@@ -388,10 +395,40 @@
388 395
389#define AR9170_MAC_REG_BCN_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd98) 396#define AR9170_MAC_REG_BCN_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd98)
390#define AR9170_MAC_REG_BCN_COUNT (AR9170_MAC_REG_BASE + 0xd9c) 397#define AR9170_MAC_REG_BCN_COUNT (AR9170_MAC_REG_BASE + 0xd9c)
391
392
393#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xda0) 398#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xda0)
399#define AR9170_MAC_BCN_HT1_HT_EN BIT(0)
400#define AR9170_MAC_BCN_HT1_GF_PMB BIT(1)
401#define AR9170_MAC_BCN_HT1_SP_EXP BIT(2)
402#define AR9170_MAC_BCN_HT1_TX_BF BIT(3)
403#define AR9170_MAC_BCN_HT1_PWR_CTRL_S 4
404#define AR9170_MAC_BCN_HT1_PWR_CTRL 0x70
405#define AR9170_MAC_BCN_HT1_TX_ANT1 BIT(7)
406#define AR9170_MAC_BCN_HT1_TX_ANT0 BIT(8)
407#define AR9170_MAC_BCN_HT1_NUM_LFT_S 9
408#define AR9170_MAC_BCN_HT1_NUM_LFT 0x600
409#define AR9170_MAC_BCN_HT1_BWC_20M_EXT BIT(16)
410#define AR9170_MAC_BCN_HT1_BWC_40M_SHARED BIT(17)
411#define AR9170_MAC_BCN_HT1_BWC_40M_DUP (BIT(16) | BIT(17))
412#define AR9170_MAC_BCN_HT1_BF_MCS_S 18
413#define AR9170_MAC_BCN_HT1_BF_MCS 0x1c0000
414#define AR9170_MAC_BCN_HT1_TPC_S 21
415#define AR9170_MAC_BCN_HT1_TPC 0x7e00000
416#define AR9170_MAC_BCN_HT1_CHAIN_MASK_S 27
417#define AR9170_MAC_BCN_HT1_CHAIN_MASK 0x38000000
418
394#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xda4) 419#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xda4)
420#define AR9170_MAC_BCN_HT2_MCS_S 0
421#define AR9170_MAC_BCN_HT2_MCS 0x7f
422#define AR9170_MAC_BCN_HT2_BW40 BIT(8)
423#define AR9170_MAC_BCN_HT2_SMOOTHING BIT(9)
424#define AR9170_MAC_BCN_HT2_SS BIT(10)
425#define AR9170_MAC_BCN_HT2_NSS BIT(11)
426#define AR9170_MAC_BCN_HT2_STBC_S 12
427#define AR9170_MAC_BCN_HT2_STBC 0x3000
428#define AR9170_MAC_BCN_HT2_ADV_COD BIT(14)
429#define AR9170_MAC_BCN_HT2_SGI BIT(15)
430#define AR9170_MAC_BCN_HT2_LEN_S 16
431#define AR9170_MAC_BCN_HT2_LEN 0xffff0000
395 432
396#define AR9170_MAC_REG_DMA_TXQX_ADDR_CURR (AR9170_MAC_REG_BASE + 0xdc0) 433#define AR9170_MAC_REG_DMA_TXQX_ADDR_CURR (AR9170_MAC_REG_BASE + 0xdc0)
397 434
diff --git a/drivers/net/wireless/ath/carl9170/led.c b/drivers/net/wireless/ath/carl9170/led.c
index 4bb2cbd8bd9b..78dadc797558 100644
--- a/drivers/net/wireless/ath/carl9170/led.c
+++ b/drivers/net/wireless/ath/carl9170/led.c
@@ -118,7 +118,7 @@ static void carl9170_led_set_brightness(struct led_classdev *led,
118 } 118 }
119 119
120 if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) 120 if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
121 ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10); 121 ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ / 10);
122} 122}
123 123
124static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name, 124static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name,
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 385cf508479b..dfda91970995 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -455,135 +455,6 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
455 return carl9170_regwrite_result(); 455 return carl9170_regwrite_result();
456} 456}
457 457
458int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
459{
460 struct sk_buff *skb = NULL;
461 struct carl9170_vif_info *cvif;
462 struct ieee80211_tx_info *txinfo;
463 __le32 *data, *old = NULL;
464 u32 word, off, addr, len;
465 int i = 0, err = 0;
466
467 rcu_read_lock();
468 cvif = rcu_dereference(ar->beacon_iter);
469retry:
470 if (ar->vifs == 0 || !cvif)
471 goto out_unlock;
472
473 list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
474 if (cvif->active && cvif->enable_beacon)
475 goto found;
476 }
477
478 if (!ar->beacon_enabled || i++)
479 goto out_unlock;
480
481 goto retry;
482
483found:
484 rcu_assign_pointer(ar->beacon_iter, cvif);
485
486 skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
487 NULL, NULL);
488
489 if (!skb) {
490 err = -ENOMEM;
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;
498 }
499
500 spin_lock_bh(&ar->beacon_lock);
501 data = (__le32 *)skb->data;
502 if (cvif->beacon)
503 old = (__le32 *)cvif->beacon->data;
504
505 off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
506 addr = ar->fw.beacon_addr + off;
507 len = roundup(skb->len + FCS_LEN, 4);
508
509 if ((off + len) > ar->fw.beacon_max_len) {
510 if (net_ratelimit()) {
511 wiphy_err(ar->hw->wiphy, "beacon does not "
512 "fit into device memory!\n");
513 }
514 err = -EINVAL;
515 goto err_unlock;
516 }
517
518 if (len > AR9170_MAC_BCN_LENGTH_MAX) {
519 if (net_ratelimit()) {
520 wiphy_err(ar->hw->wiphy, "no support for beacons "
521 "bigger than %d (yours:%d).\n",
522 AR9170_MAC_BCN_LENGTH_MAX, len);
523 }
524
525 err = -EMSGSIZE;
526 goto err_unlock;
527 }
528
529 i = txinfo->control.rates[0].idx;
530 if (txinfo->band != IEEE80211_BAND_2GHZ)
531 i += 4;
532
533 word = __carl9170_ratetable[i].hw_value & 0xf;
534 if (i < 4)
535 word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
536 else
537 word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
538
539 carl9170_async_regwrite_begin(ar);
540 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
541
542 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
543 /*
544 * XXX: This accesses beyond skb data for up
545 * to the last 3 bytes!!
546 */
547
548 if (old && (data[i] == old[i]))
549 continue;
550
551 word = le32_to_cpu(data[i]);
552 carl9170_async_regwrite(addr + 4 * i, word);
553 }
554 carl9170_async_regwrite_finish();
555
556 dev_kfree_skb_any(cvif->beacon);
557 cvif->beacon = NULL;
558
559 err = carl9170_async_regwrite_result();
560 if (!err)
561 cvif->beacon = skb;
562 spin_unlock_bh(&ar->beacon_lock);
563 if (err)
564 goto err_free;
565
566 if (submit) {
567 err = carl9170_bcn_ctrl(ar, cvif->id,
568 CARL9170_BCN_CTRL_CAB_TRIGGER,
569 addr, skb->len + FCS_LEN);
570
571 if (err)
572 goto err_free;
573 }
574out_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);
584 return err;
585}
586
587int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, 458int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
588 const u8 ktype, const u8 keyidx, const u8 *keydata, 459 const u8 ktype, const u8 keyidx, const u8 *keydata,
589 const int keylen) 460 const int keylen)
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index a61cf6781d5e..0122930b14c7 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1630,7 +1630,7 @@ static int carl9170_read_eeprom(struct ar9170 *ar)
1630 BUILD_BUG_ON(sizeof(ar->eeprom) % RB); 1630 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
1631#endif 1631#endif
1632 1632
1633 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) { 1633 for (i = 0; i < sizeof(ar->eeprom) / RB; i++) {
1634 for (j = 0; j < RW; j++) 1634 for (j = 0; j < RW; j++)
1635 offsets[j] = cpu_to_le32(AR9170_EEPROM_START + 1635 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
1636 RB * i + 4 * j); 1636 RB * i + 4 * j);
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index da1ab962ee48..aa147a9120b6 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1098,7 +1098,7 @@ static u8 carl9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
1098 * Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)? 1098 * Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
1099 * Can we rely on the compiler to optimise away the div? 1099 * Can we rely on the compiler to optimise away the div?
1100 */ 1100 */
1101 return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1)); 1101 return (y >> SHIFT) + ((y & (1 << (SHIFT - 1))) >> (SHIFT - 1));
1102#undef SHIFT 1102#undef SHIFT
1103} 1103}
1104 1104
@@ -1379,7 +1379,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
1379 1379
1380 modes[i].max_power = 1380 modes[i].max_power =
1381 carl9170_get_max_edge_power(ar, 1381 carl9170_get_max_edge_power(ar,
1382 freq+f_off, EDGES(ctl_idx, 1)); 1382 freq + f_off, EDGES(ctl_idx, 1));
1383 1383
1384 /* 1384 /*
1385 * TODO: check if the regulatory max. power is 1385 * TODO: check if the regulatory max. power is
@@ -1441,7 +1441,7 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
1441 if (freq < 3000) 1441 if (freq < 3000)
1442 f = freq - 2300; 1442 f = freq - 2300;
1443 else 1443 else
1444 f = (freq - 4800)/5; 1444 f = (freq - 4800) / 5;
1445 1445
1446 /* 1446 /*
1447 * cycle through the various modes 1447 * cycle through the various modes
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index e94084fcf6f5..d20946939cd8 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -661,11 +661,67 @@ void carl9170_tx_process_status(struct ar9170 *ar,
661 } 661 }
662} 662}
663 663
664static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar,
665 struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate,
666 unsigned int *phyrate, unsigned int *tpc, unsigned int *chains)
667{
668 struct ieee80211_rate *rate = NULL;
669 u8 *txpower;
670 unsigned int idx;
671
672 idx = txrate->idx;
673 *tpc = 0;
674 *phyrate = 0;
675
676 if (txrate->flags & IEEE80211_TX_RC_MCS) {
677 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
678 /* +1 dBm for HT40 */
679 *tpc += 2;
680
681 if (info->band == IEEE80211_BAND_2GHZ)
682 txpower = ar->power_2G_ht40;
683 else
684 txpower = ar->power_5G_ht40;
685 } else {
686 if (info->band == IEEE80211_BAND_2GHZ)
687 txpower = ar->power_2G_ht20;
688 else
689 txpower = ar->power_5G_ht20;
690 }
691
692 *phyrate = txrate->idx;
693 *tpc += txpower[idx & 7];
694 } else {
695 if (info->band == IEEE80211_BAND_2GHZ) {
696 if (idx < 4)
697 txpower = ar->power_2G_cck;
698 else
699 txpower = ar->power_2G_ofdm;
700 } else {
701 txpower = ar->power_5G_leg;
702 idx += 4;
703 }
704
705 rate = &__carl9170_ratetable[idx];
706 *tpc += txpower[(rate->hw_value & 0x30) >> 4];
707 *phyrate = rate->hw_value & 0xf;
708 }
709
710 if (ar->eeprom.tx_mask == 1) {
711 *chains = AR9170_TX_PHY_TXCHAIN_1;
712 } else {
713 if (!(txrate->flags & IEEE80211_TX_RC_MCS) &&
714 rate && rate->bitrate >= 360)
715 *chains = AR9170_TX_PHY_TXCHAIN_1;
716 else
717 *chains = AR9170_TX_PHY_TXCHAIN_2;
718 }
719}
720
664static __le32 carl9170_tx_physet(struct ar9170 *ar, 721static __le32 carl9170_tx_physet(struct ar9170 *ar,
665 struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate) 722 struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate)
666{ 723{
667 struct ieee80211_rate *rate = NULL; 724 unsigned int power = 0, chains = 0, phyrate = 0;
668 u32 power, chains;
669 __le32 tmp; 725 __le32 tmp;
670 726
671 tmp = cpu_to_le32(0); 727 tmp = cpu_to_le32(0);
@@ -682,35 +738,12 @@ static __le32 carl9170_tx_physet(struct ar9170 *ar,
682 tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI); 738 tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
683 739
684 if (txrate->flags & IEEE80211_TX_RC_MCS) { 740 if (txrate->flags & IEEE80211_TX_RC_MCS) {
685 u32 r = txrate->idx; 741 SET_VAL(AR9170_TX_PHY_MCS, phyrate, txrate->idx);
686 u8 *txpower;
687 742
688 /* heavy clip control */ 743 /* heavy clip control */
689 tmp |= cpu_to_le32((r & 0x7) << 744 tmp |= cpu_to_le32((txrate->idx & 0x7) <<
690 AR9170_TX_PHY_TX_HEAVY_CLIP_S); 745 AR9170_TX_PHY_TX_HEAVY_CLIP_S);
691 746
692 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
693 if (info->band == IEEE80211_BAND_5GHZ)
694 txpower = ar->power_5G_ht40;
695 else
696 txpower = ar->power_2G_ht40;
697 } else {
698 if (info->band == IEEE80211_BAND_5GHZ)
699 txpower = ar->power_5G_ht20;
700 else
701 txpower = ar->power_2G_ht20;
702 }
703
704 power = txpower[r & 7];
705
706 /* +1 dBm for HT40 */
707 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
708 power += 2;
709
710 r <<= AR9170_TX_PHY_MCS_S;
711 BUG_ON(r & ~AR9170_TX_PHY_MCS);
712
713 tmp |= cpu_to_le32(r & AR9170_TX_PHY_MCS);
714 tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); 747 tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
715 748
716 /* 749 /*
@@ -720,34 +753,15 @@ static __le32 carl9170_tx_physet(struct ar9170 *ar,
720 * tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); 753 * tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
721 */ 754 */
722 } else { 755 } else {
723 u8 *txpower; 756 if (info->band == IEEE80211_BAND_2GHZ) {
724 u32 mod; 757 if (txrate->idx <= AR9170_TX_PHY_RATE_CCK_11M)
725 u32 phyrate; 758 tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_CCK);
726 u8 idx = txrate->idx; 759 else
727 760 tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_OFDM);
728 if (info->band != IEEE80211_BAND_2GHZ) {
729 idx += 4;
730 txpower = ar->power_5G_leg;
731 mod = AR9170_TX_PHY_MOD_OFDM;
732 } else { 761 } else {
733 if (idx < 4) { 762 tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_OFDM);
734 txpower = ar->power_2G_cck;
735 mod = AR9170_TX_PHY_MOD_CCK;
736 } else {
737 mod = AR9170_TX_PHY_MOD_OFDM;
738 txpower = ar->power_2G_ofdm;
739 }
740 } 763 }
741 764
742 rate = &__carl9170_ratetable[idx];
743
744 phyrate = rate->hw_value & 0xF;
745 power = txpower[(rate->hw_value & 0x30) >> 4];
746 phyrate <<= AR9170_TX_PHY_MCS_S;
747
748 tmp |= cpu_to_le32(mod);
749 tmp |= cpu_to_le32(phyrate);
750
751 /* 765 /*
752 * short preamble seems to be broken too. 766 * short preamble seems to be broken too.
753 * 767 *
@@ -755,23 +769,12 @@ static __le32 carl9170_tx_physet(struct ar9170 *ar,
755 * tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE); 769 * tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
756 */ 770 */
757 } 771 }
758 power <<= AR9170_TX_PHY_TX_PWR_S; 772 carl9170_tx_rate_tpc_chains(ar, info, txrate,
759 power &= AR9170_TX_PHY_TX_PWR; 773 &phyrate, &power, &chains);
760 tmp |= cpu_to_le32(power);
761
762 /* set TX chains */
763 if (ar->eeprom.tx_mask == 1) {
764 chains = AR9170_TX_PHY_TXCHAIN_1;
765 } else {
766 chains = AR9170_TX_PHY_TXCHAIN_2;
767
768 /* >= 36M legacy OFDM - use only one chain */
769 if (rate && rate->bitrate >= 360 &&
770 !(txrate->flags & IEEE80211_TX_RC_MCS))
771 chains = AR9170_TX_PHY_TXCHAIN_1;
772 }
773 tmp |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_S);
774 774
775 tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_MCS, phyrate));
776 tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_TX_PWR, power));
777 tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_TXCHAIN, chains));
775 return tmp; 778 return tmp;
776} 779}
777 780
@@ -1438,3 +1441,154 @@ void carl9170_tx_scheduler(struct ar9170 *ar)
1438 if (ar->tx_schedule) 1441 if (ar->tx_schedule)
1439 carl9170_tx(ar); 1442 carl9170_tx(ar);
1440} 1443}
1444
1445int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
1446{
1447 struct sk_buff *skb = NULL;
1448 struct carl9170_vif_info *cvif;
1449 struct ieee80211_tx_info *txinfo;
1450 struct ieee80211_tx_rate *rate;
1451 __le32 *data, *old = NULL;
1452 unsigned int plcp, power, chains;
1453 u32 word, ht1, off, addr, len;
1454 int i = 0, err = 0;
1455
1456 rcu_read_lock();
1457 cvif = rcu_dereference(ar->beacon_iter);
1458retry:
1459 if (ar->vifs == 0 || !cvif)
1460 goto out_unlock;
1461
1462 list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
1463 if (cvif->active && cvif->enable_beacon)
1464 goto found;
1465 }
1466
1467 if (!ar->beacon_enabled || i++)
1468 goto out_unlock;
1469
1470 goto retry;
1471
1472found:
1473 rcu_assign_pointer(ar->beacon_iter, cvif);
1474
1475 skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
1476 NULL, NULL);
1477
1478 if (!skb) {
1479 err = -ENOMEM;
1480 goto err_free;
1481 }
1482
1483 txinfo = IEEE80211_SKB_CB(skb);
1484 spin_lock_bh(&ar->beacon_lock);
1485 data = (__le32 *)skb->data;
1486 if (cvif->beacon)
1487 old = (__le32 *)cvif->beacon->data;
1488
1489 off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
1490 addr = ar->fw.beacon_addr + off;
1491 len = roundup(skb->len + FCS_LEN, 4);
1492
1493 if ((off + len) > ar->fw.beacon_max_len) {
1494 if (net_ratelimit()) {
1495 wiphy_err(ar->hw->wiphy, "beacon does not "
1496 "fit into device memory!\n");
1497 }
1498 err = -EINVAL;
1499 goto err_unlock;
1500 }
1501
1502 if (len > AR9170_MAC_BCN_LENGTH_MAX) {
1503 if (net_ratelimit()) {
1504 wiphy_err(ar->hw->wiphy, "no support for beacons "
1505 "bigger than %d (yours:%d).\n",
1506 AR9170_MAC_BCN_LENGTH_MAX, len);
1507 }
1508
1509 err = -EMSGSIZE;
1510 goto err_unlock;
1511 }
1512
1513 ht1 = AR9170_MAC_BCN_HT1_TX_ANT0;
1514 rate = &txinfo->control.rates[0];
1515 carl9170_tx_rate_tpc_chains(ar, txinfo, rate, &plcp, &power, &chains);
1516 if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) {
1517 if (plcp <= AR9170_TX_PHY_RATE_CCK_11M)
1518 plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
1519 else
1520 plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010;
1521 } else {
1522 ht1 |= AR9170_MAC_BCN_HT1_HT_EN;
1523 if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
1524 plcp |= AR9170_MAC_BCN_HT2_SGI;
1525
1526 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1527 ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED;
1528 plcp |= AR9170_MAC_BCN_HT2_BW40;
1529 }
1530 if (rate->flags & IEEE80211_TX_RC_DUP_DATA) {
1531 ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP;
1532 plcp |= AR9170_MAC_BCN_HT2_BW40;
1533 }
1534
1535 SET_VAL(AR9170_MAC_BCN_HT2_LEN, plcp, skb->len + FCS_LEN);
1536 }
1537
1538 SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, ht1, 7);
1539 SET_VAL(AR9170_MAC_BCN_HT1_TPC, ht1, power);
1540 SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, ht1, chains);
1541 if (chains == AR9170_TX_PHY_TXCHAIN_2)
1542 ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1;
1543
1544 carl9170_async_regwrite_begin(ar);
1545 carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT1, ht1);
1546 if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS))
1547 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, plcp);
1548 else
1549 carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT2, plcp);
1550
1551 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
1552 /*
1553 * XXX: This accesses beyond skb data for up
1554 * to the last 3 bytes!!
1555 */
1556
1557 if (old && (data[i] == old[i]))
1558 continue;
1559
1560 word = le32_to_cpu(data[i]);
1561 carl9170_async_regwrite(addr + 4 * i, word);
1562 }
1563 carl9170_async_regwrite_finish();
1564
1565 dev_kfree_skb_any(cvif->beacon);
1566 cvif->beacon = NULL;
1567
1568 err = carl9170_async_regwrite_result();
1569 if (!err)
1570 cvif->beacon = skb;
1571 spin_unlock_bh(&ar->beacon_lock);
1572 if (err)
1573 goto err_free;
1574
1575 if (submit) {
1576 err = carl9170_bcn_ctrl(ar, cvif->id,
1577 CARL9170_BCN_CTRL_CAB_TRIGGER,
1578 addr, skb->len + FCS_LEN);
1579
1580 if (err)
1581 goto err_free;
1582 }
1583out_unlock:
1584 rcu_read_unlock();
1585 return 0;
1586
1587err_unlock:
1588 spin_unlock_bh(&ar->beacon_lock);
1589
1590err_free:
1591 rcu_read_unlock();
1592 dev_kfree_skb_any(skb);
1593 return err;
1594}