aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/htc_drv_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c95
1 files changed, 82 insertions, 13 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 4de38643cb53..5aa104fe7eeb 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -332,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
332 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); 332 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
333 hvif.index = priv->mon_vif_idx; 333 hvif.index = priv->mon_vif_idx;
334 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); 334 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
335 if (ret) {
336 ath_err(common, "Unable to remove monitor interface at idx: %d\n",
337 priv->mon_vif_idx);
338 }
339
335 priv->nvifs--; 340 priv->nvifs--;
336 priv->vif_slot &= ~(1 << priv->mon_vif_idx); 341 priv->vif_slot &= ~(1 << priv->mon_vif_idx);
337} 342}
@@ -462,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
462 struct ath9k_htc_sta *ista; 467 struct ath9k_htc_sta *ista;
463 int ret, sta_idx; 468 int ret, sta_idx;
464 u8 cmd_rsp; 469 u8 cmd_rsp;
470 u16 maxampdu;
465 471
466 if (priv->nstations >= ATH9K_HTC_MAX_STA) 472 if (priv->nstations >= ATH9K_HTC_MAX_STA)
467 return -ENOBUFS; 473 return -ENOBUFS;
@@ -485,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
485 491
486 tsta.sta_index = sta_idx; 492 tsta.sta_index = sta_idx;
487 tsta.vif_index = avp->index; 493 tsta.vif_index = avp->index;
488 tsta.maxampdu = cpu_to_be16(0xffff); 494
495 if (!sta) {
496 tsta.maxampdu = cpu_to_be16(0xffff);
497 } else {
498 maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
499 sta->ht_cap.ampdu_factor);
500 tsta.maxampdu = cpu_to_be16(maxampdu);
501 }
502
489 if (sta && sta->ht_cap.ht_supported) 503 if (sta && sta->ht_cap.ht_supported)
490 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); 504 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
491 505
@@ -558,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
558 return 0; 572 return 0;
559} 573}
560 574
561int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) 575int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
576 u8 enable_coex)
562{ 577{
563 struct ath9k_htc_cap_target tcap; 578 struct ath9k_htc_cap_target tcap;
564 int ret; 579 int ret;
@@ -566,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
566 581
567 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); 582 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
568 583
569 /* FIXME: Values are hardcoded */ 584 tcap.ampdu_limit = cpu_to_be32(0xffff);
570 tcap.flags = 0x240c40; 585 tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes;
571 tcap.flags_ext = 0x80601000; 586 tcap.enable_coex = enable_coex;
572 tcap.ampdu_limit = 0xffff0000;
573 tcap.ampdu_subframes = 20;
574 tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
575 tcap.protmode = 1;
576 tcap.tx_chainmask = priv->ah->caps.tx_chainmask; 587 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
577 588
578 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); 589 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
@@ -931,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
931 942
932 ath9k_host_rx_init(priv); 943 ath9k_host_rx_init(priv);
933 944
934 ret = ath9k_htc_update_cap_target(priv); 945 ret = ath9k_htc_update_cap_target(priv, 0);
935 if (ret) 946 if (ret)
936 ath_dbg(common, ATH_DBG_CONFIG, 947 ath_dbg(common, ATH_DBG_CONFIG,
937 "Failed to update capability in target\n"); 948 "Failed to update capability in target\n");
@@ -964,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
964 struct ath9k_htc_priv *priv = hw->priv; 975 struct ath9k_htc_priv *priv = hw->priv;
965 struct ath_hw *ah = priv->ah; 976 struct ath_hw *ah = priv->ah;
966 struct ath_common *common = ath9k_hw_common(ah); 977 struct ath_common *common = ath9k_hw_common(ah);
967 int ret = 0; 978 int ret __attribute__ ((unused));
968 u8 cmd_rsp; 979 u8 cmd_rsp;
969 980
970 mutex_lock(&priv->mutex); 981 mutex_lock(&priv->mutex);
@@ -992,9 +1003,11 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
992 /* Cancel all the running timers/work .. */ 1003 /* Cancel all the running timers/work .. */
993 cancel_work_sync(&priv->fatal_work); 1004 cancel_work_sync(&priv->fatal_work);
994 cancel_work_sync(&priv->ps_work); 1005 cancel_work_sync(&priv->ps_work);
995 cancel_delayed_work_sync(&priv->ath9k_led_blink_work); 1006
1007#ifdef CONFIG_MAC80211_LEDS
1008 cancel_work_sync(&priv->led_work);
1009#endif
996 ath9k_htc_stop_ani(priv); 1010 ath9k_htc_stop_ani(priv);
997 ath9k_led_stop_brightness(priv);
998 1011
999 mutex_lock(&priv->mutex); 1012 mutex_lock(&priv->mutex);
1000 1013
@@ -1135,6 +1148,10 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1135 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); 1148 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1136 hvif.index = avp->index; 1149 hvif.index = avp->index;
1137 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); 1150 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1151 if (ret) {
1152 ath_err(common, "Unable to remove interface at idx: %d\n",
1153 avp->index);
1154 }
1138 priv->nvifs--; 1155 priv->nvifs--;
1139 priv->vif_slot &= ~(1 << avp->index); 1156 priv->vif_slot &= ~(1 << avp->index);
1140 1157
@@ -1567,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1567 int ret = 0; 1584 int ret = 0;
1568 1585
1569 mutex_lock(&priv->mutex); 1586 mutex_lock(&priv->mutex);
1587 ath9k_htc_ps_wakeup(priv);
1570 1588
1571 switch (action) { 1589 switch (action) {
1572 case IEEE80211_AMPDU_RX_START: 1590 case IEEE80211_AMPDU_RX_START:
@@ -1592,6 +1610,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1592 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); 1610 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
1593 } 1611 }
1594 1612
1613 ath9k_htc_ps_restore(priv);
1595 mutex_unlock(&priv->mutex); 1614 mutex_unlock(&priv->mutex);
1596 1615
1597 return ret; 1616 return ret;
@@ -1642,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1642 mutex_unlock(&priv->mutex); 1661 mutex_unlock(&priv->mutex);
1643} 1662}
1644 1663
1664/*
1665 * Currently, this is used only for selecting the minimum rate
1666 * for management frames, rate selection for data frames remain
1667 * unaffected.
1668 */
1669static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
1670 struct ieee80211_vif *vif,
1671 const struct cfg80211_bitrate_mask *mask)
1672{
1673 struct ath9k_htc_priv *priv = hw->priv;
1674 struct ath_common *common = ath9k_hw_common(priv->ah);
1675 struct ath9k_htc_target_rate_mask tmask;
1676 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1677 int ret = 0;
1678 u8 cmd_rsp;
1679
1680 memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
1681
1682 tmask.vif_index = avp->index;
1683 tmask.band = IEEE80211_BAND_2GHZ;
1684 tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
1685
1686 WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1687 if (ret) {
1688 ath_err(common,
1689 "Unable to set 2G rate mask for "
1690 "interface at idx: %d\n", avp->index);
1691 goto out;
1692 }
1693
1694 tmask.band = IEEE80211_BAND_5GHZ;
1695 tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
1696
1697 WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1698 if (ret) {
1699 ath_err(common,
1700 "Unable to set 5G rate mask for "
1701 "interface at idx: %d\n", avp->index);
1702 goto out;
1703 }
1704
1705 ath_dbg(common, ATH_DBG_CONFIG,
1706 "Set bitrate masks: 0x%x, 0x%x\n",
1707 mask->control[IEEE80211_BAND_2GHZ].legacy,
1708 mask->control[IEEE80211_BAND_5GHZ].legacy);
1709out:
1710 return ret;
1711}
1712
1645struct ieee80211_ops ath9k_htc_ops = { 1713struct ieee80211_ops ath9k_htc_ops = {
1646 .tx = ath9k_htc_tx, 1714 .tx = ath9k_htc_tx,
1647 .start = ath9k_htc_start, 1715 .start = ath9k_htc_start,
@@ -1664,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = {
1664 .set_rts_threshold = ath9k_htc_set_rts_threshold, 1732 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1665 .rfkill_poll = ath9k_htc_rfkill_poll_state, 1733 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1666 .set_coverage_class = ath9k_htc_set_coverage_class, 1734 .set_coverage_class = ath9k_htc_set_coverage_class,
1735 .set_bitrate_mask = ath9k_htc_set_bitrate_mask,
1667}; 1736};