diff options
Diffstat (limited to 'drivers/net/wireless/ath/carl9170/main.c')
-rw-r--r-- | drivers/net/wireless/ath/carl9170/main.c | 113 |
1 files changed, 89 insertions, 24 deletions
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 25a1e2f4f738..ef82751722e0 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -358,8 +358,13 @@ static int carl9170_op_start(struct ieee80211_hw *hw) | |||
358 | ar->ps.last_action = jiffies; | 358 | ar->ps.last_action = jiffies; |
359 | ar->ps.last_slept = jiffies; | 359 | ar->ps.last_slept = jiffies; |
360 | ar->erp_mode = CARL9170_ERP_AUTO; | 360 | ar->erp_mode = CARL9170_ERP_AUTO; |
361 | ar->rx_software_decryption = false; | 361 | |
362 | ar->disable_offload = false; | 362 | /* Set "disable hw crypto offload" whenever the module parameter |
363 | * nohwcrypt is true or if the firmware does not support it. | ||
364 | */ | ||
365 | ar->disable_offload = modparam_nohwcrypt | | ||
366 | ar->fw.disable_offload_fw; | ||
367 | ar->rx_software_decryption = ar->disable_offload; | ||
363 | 368 | ||
364 | for (i = 0; i < ar->hw->queues; i++) { | 369 | for (i = 0; i < ar->hw->queues; i++) { |
365 | ar->queue_stop_timeout[i] = jiffies; | 370 | ar->queue_stop_timeout[i] = jiffies; |
@@ -565,12 +570,28 @@ static int carl9170_init_interface(struct ar9170 *ar, | |||
565 | 570 | ||
566 | memcpy(common->macaddr, vif->addr, ETH_ALEN); | 571 | memcpy(common->macaddr, vif->addr, ETH_ALEN); |
567 | 572 | ||
568 | if (modparam_nohwcrypt || | 573 | /* We have to fall back to software crypto, whenever |
569 | ((vif->type != NL80211_IFTYPE_STATION) && | 574 | * the user choose to participates in an IBSS. HW |
570 | (vif->type != NL80211_IFTYPE_AP))) { | 575 | * offload for IBSS RSN is not supported by this driver. |
571 | ar->rx_software_decryption = true; | 576 | * |
572 | ar->disable_offload = true; | 577 | * NOTE: If the previous main interface has already |
573 | } | 578 | * disabled hw crypto offload, we have to keep this |
579 | * previous disable_offload setting as it was. | ||
580 | * Altough ideally, we should notify mac80211 and tell | ||
581 | * it to forget about any HW crypto offload for now. | ||
582 | */ | ||
583 | ar->disable_offload |= ((vif->type != NL80211_IFTYPE_STATION) && | ||
584 | (vif->type != NL80211_IFTYPE_AP)); | ||
585 | |||
586 | /* While the driver supports HW offload in a single | ||
587 | * P2P client configuration, it doesn't support HW | ||
588 | * offload in the favourit, concurrent P2P GO+CLIENT | ||
589 | * configuration. Hence, HW offload will always be | ||
590 | * disabled for P2P. | ||
591 | */ | ||
592 | ar->disable_offload |= vif->p2p; | ||
593 | |||
594 | ar->rx_software_decryption = ar->disable_offload; | ||
574 | 595 | ||
575 | err = carl9170_set_operating_mode(ar); | 596 | err = carl9170_set_operating_mode(ar); |
576 | return err; | 597 | return err; |
@@ -580,7 +601,7 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, | |||
580 | struct ieee80211_vif *vif) | 601 | struct ieee80211_vif *vif) |
581 | { | 602 | { |
582 | struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; | 603 | struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; |
583 | struct ieee80211_vif *main_vif; | 604 | struct ieee80211_vif *main_vif, *old_main = NULL; |
584 | struct ar9170 *ar = hw->priv; | 605 | struct ar9170 *ar = hw->priv; |
585 | int vif_id = -1, err = 0; | 606 | int vif_id = -1, err = 0; |
586 | 607 | ||
@@ -602,6 +623,15 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, | |||
602 | goto init; | 623 | goto init; |
603 | } | 624 | } |
604 | 625 | ||
626 | /* Because the AR9170 HW's MAC doesn't provide full support for | ||
627 | * multiple, independent interfaces [of different operation modes]. | ||
628 | * We have to select ONE main interface [main mode of HW], but we | ||
629 | * can have multiple slaves [AKA: entry in the ACK-table]. | ||
630 | * | ||
631 | * The first (from HEAD/TOP) interface in the ar->vif_list is | ||
632 | * always the main intf. All following intfs in this list | ||
633 | * are considered to be slave intfs. | ||
634 | */ | ||
605 | main_vif = carl9170_get_main_vif(ar); | 635 | main_vif = carl9170_get_main_vif(ar); |
606 | 636 | ||
607 | if (main_vif) { | 637 | if (main_vif) { |
@@ -610,6 +640,18 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, | |||
610 | if (vif->type == NL80211_IFTYPE_STATION) | 640 | if (vif->type == NL80211_IFTYPE_STATION) |
611 | break; | 641 | break; |
612 | 642 | ||
643 | /* P2P GO [master] use-case | ||
644 | * Because the P2P GO station is selected dynamically | ||
645 | * by all participating peers of a WIFI Direct network, | ||
646 | * the driver has be able to change the main interface | ||
647 | * operating mode on the fly. | ||
648 | */ | ||
649 | if (main_vif->p2p && vif->p2p && | ||
650 | vif->type == NL80211_IFTYPE_AP) { | ||
651 | old_main = main_vif; | ||
652 | break; | ||
653 | } | ||
654 | |||
613 | err = -EBUSY; | 655 | err = -EBUSY; |
614 | rcu_read_unlock(); | 656 | rcu_read_unlock(); |
615 | 657 | ||
@@ -648,14 +690,41 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, | |||
648 | vif_priv->id = vif_id; | 690 | vif_priv->id = vif_id; |
649 | vif_priv->enable_beacon = false; | 691 | vif_priv->enable_beacon = false; |
650 | ar->vifs++; | 692 | ar->vifs++; |
651 | list_add_tail_rcu(&vif_priv->list, &ar->vif_list); | 693 | if (old_main) { |
694 | /* We end up in here, if the main interface is being replaced. | ||
695 | * Put the new main interface at the HEAD of the list and the | ||
696 | * previous inteface will automatically become second in line. | ||
697 | */ | ||
698 | list_add_rcu(&vif_priv->list, &ar->vif_list); | ||
699 | } else { | ||
700 | /* Add new inteface. If the list is empty, it will become the | ||
701 | * main inteface, otherwise it will be slave. | ||
702 | */ | ||
703 | list_add_tail_rcu(&vif_priv->list, &ar->vif_list); | ||
704 | } | ||
652 | rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif); | 705 | rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif); |
653 | 706 | ||
654 | init: | 707 | init: |
655 | if (carl9170_get_main_vif(ar) == vif) { | 708 | main_vif = carl9170_get_main_vif(ar); |
709 | |||
710 | if (main_vif == vif) { | ||
656 | rcu_assign_pointer(ar->beacon_iter, vif_priv); | 711 | rcu_assign_pointer(ar->beacon_iter, vif_priv); |
657 | rcu_read_unlock(); | 712 | rcu_read_unlock(); |
658 | 713 | ||
714 | if (old_main) { | ||
715 | struct carl9170_vif_info *old_main_priv = | ||
716 | (void *) old_main->drv_priv; | ||
717 | /* downgrade old main intf to slave intf. | ||
718 | * NOTE: We are no longer under rcu_read_lock. | ||
719 | * But we are still holding ar->mutex, so the | ||
720 | * vif data [id, addr] is safe. | ||
721 | */ | ||
722 | err = carl9170_mod_virtual_mac(ar, old_main_priv->id, | ||
723 | old_main->addr); | ||
724 | if (err) | ||
725 | goto unlock; | ||
726 | } | ||
727 | |||
659 | err = carl9170_init_interface(ar, vif); | 728 | err = carl9170_init_interface(ar, vif); |
660 | if (err) | 729 | if (err) |
661 | goto unlock; | 730 | goto unlock; |
@@ -1112,9 +1181,7 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
1112 | if (ar->disable_offload || !vif) | 1181 | if (ar->disable_offload || !vif) |
1113 | return -EOPNOTSUPP; | 1182 | return -EOPNOTSUPP; |
1114 | 1183 | ||
1115 | /* | 1184 | /* Fall back to software encryption whenever the driver is connected |
1116 | * We have to fall back to software encryption, whenever | ||
1117 | * the user choose to participates in an IBSS or is connected | ||
1118 | * to more than one network. | 1185 | * to more than one network. |
1119 | * | 1186 | * |
1120 | * This is very unfortunate, because some machines cannot handle | 1187 | * This is very unfortunate, because some machines cannot handle |
@@ -1263,7 +1330,7 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, | |||
1263 | return 0; | 1330 | return 0; |
1264 | } | 1331 | } |
1265 | 1332 | ||
1266 | for (i = 0; i < CARL9170_NUM_TID; i++) | 1333 | for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++) |
1267 | RCU_INIT_POINTER(sta_info->agg[i], NULL); | 1334 | RCU_INIT_POINTER(sta_info->agg[i], NULL); |
1268 | 1335 | ||
1269 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); | 1336 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); |
@@ -1287,7 +1354,7 @@ static int carl9170_op_sta_remove(struct ieee80211_hw *hw, | |||
1287 | sta_info->ht_sta = false; | 1354 | sta_info->ht_sta = false; |
1288 | 1355 | ||
1289 | rcu_read_lock(); | 1356 | rcu_read_lock(); |
1290 | for (i = 0; i < CARL9170_NUM_TID; i++) { | 1357 | for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++) { |
1291 | struct carl9170_sta_tid *tid_info; | 1358 | struct carl9170_sta_tid *tid_info; |
1292 | 1359 | ||
1293 | tid_info = rcu_dereference(sta_info->agg[i]); | 1360 | tid_info = rcu_dereference(sta_info->agg[i]); |
@@ -1394,7 +1461,9 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, | |||
1394 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1461 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1395 | break; | 1462 | break; |
1396 | 1463 | ||
1397 | case IEEE80211_AMPDU_TX_STOP: | 1464 | case IEEE80211_AMPDU_TX_STOP_CONT: |
1465 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
1466 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
1398 | rcu_read_lock(); | 1467 | rcu_read_lock(); |
1399 | tid_info = rcu_dereference(sta_info->agg[tid]); | 1468 | tid_info = rcu_dereference(sta_info->agg[tid]); |
1400 | if (tid_info) { | 1469 | if (tid_info) { |
@@ -1805,10 +1874,6 @@ void *carl9170_alloc(size_t priv_size) | |||
1805 | for (i = 0; i < ARRAY_SIZE(ar->noise); i++) | 1874 | for (i = 0; i < ARRAY_SIZE(ar->noise); i++) |
1806 | ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ | 1875 | ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ |
1807 | 1876 | ||
1808 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1809 | |||
1810 | /* As IBSS Encryption is software-based, IBSS RSN is supported. */ | ||
1811 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | ||
1812 | return ar; | 1877 | return ar; |
1813 | 1878 | ||
1814 | err_nomem: | 1879 | err_nomem: |
@@ -1916,13 +1981,13 @@ static int carl9170_parse_eeprom(struct ar9170 *ar) | |||
1916 | return 0; | 1981 | return 0; |
1917 | } | 1982 | } |
1918 | 1983 | ||
1919 | static int carl9170_reg_notifier(struct wiphy *wiphy, | 1984 | static void carl9170_reg_notifier(struct wiphy *wiphy, |
1920 | struct regulatory_request *request) | 1985 | struct regulatory_request *request) |
1921 | { | 1986 | { |
1922 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 1987 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
1923 | struct ar9170 *ar = hw->priv; | 1988 | struct ar9170 *ar = hw->priv; |
1924 | 1989 | ||
1925 | return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory); | 1990 | ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory); |
1926 | } | 1991 | } |
1927 | 1992 | ||
1928 | int carl9170_register(struct ar9170 *ar) | 1993 | int carl9170_register(struct ar9170 *ar) |