diff options
Diffstat (limited to 'drivers/net/wireless/ath/carl9170')
-rw-r--r-- | drivers/net/wireless/ath/carl9170/carl9170.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/cmd.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/debug.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/fwdesc.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/hw.h | 41 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/led.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/mac.c | 129 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/phy.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/tx.c | 290 |
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 | ||
178 | struct carl9170_vif { | 178 | struct 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 | ||
183 | struct carl9170_vif_info { | 183 | struct 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); | |||
532 | int carl9170_set_slot_time(struct ar9170 *ar); | 532 | int carl9170_set_slot_time(struct ar9170 *ar); |
533 | int carl9170_set_mac_rates(struct ar9170 *ar); | 533 | int carl9170_set_mac_rates(struct ar9170 *ar); |
534 | int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); | 534 | int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); |
535 | int carl9170_update_beacon(struct ar9170 *ar, const bool submit); | ||
536 | int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, | 535 | int 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); |
538 | int carl9170_disable_key(struct ar9170 *ar, const u8 id); | 537 | int carl9170_disable_key(struct ar9170 *ar, const u8 id); |
@@ -553,6 +552,7 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb); | |||
553 | void carl9170_tx_scheduler(struct ar9170 *ar); | 552 | void carl9170_tx_scheduler(struct ar9170 *ar); |
554 | void carl9170_tx_get_skb(struct sk_buff *skb); | 553 | void carl9170_tx_get_skb(struct sk_buff *skb); |
555 | int carl9170_tx_put_skb(struct sk_buff *skb); | 554 | int carl9170_tx_put_skb(struct sk_buff *skb); |
555 | int 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 | ||
698 | static const char *erp_modes[] = { | 698 | static 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 | ||
124 | static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name, | 124 | static 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 | ||
458 | int 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); | ||
469 | retry: | ||
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 | |||
483 | found: | ||
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 | } | ||
574 | out_unlock: | ||
575 | rcu_read_unlock(); | ||
576 | return 0; | ||
577 | |||
578 | err_unlock: | ||
579 | spin_unlock_bh(&ar->beacon_lock); | ||
580 | |||
581 | err_free: | ||
582 | rcu_read_unlock(); | ||
583 | dev_kfree_skb_any(skb); | ||
584 | return err; | ||
585 | } | ||
586 | |||
587 | int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, | 458 | int 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 | ||
664 | static 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 | |||
664 | static __le32 carl9170_tx_physet(struct ar9170 *ar, | 721 | static __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 | |||
1445 | int 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); | ||
1458 | retry: | ||
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 | |||
1472 | found: | ||
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 | } | ||
1583 | out_unlock: | ||
1584 | rcu_read_unlock(); | ||
1585 | return 0; | ||
1586 | |||
1587 | err_unlock: | ||
1588 | spin_unlock_bh(&ar->beacon_lock); | ||
1589 | |||
1590 | err_free: | ||
1591 | rcu_read_unlock(); | ||
1592 | dev_kfree_skb_any(skb); | ||
1593 | return err; | ||
1594 | } | ||