aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-15 16:57:18 -0400
committerDavid S. Miller <davem@davemloft.net>2011-03-15 16:57:18 -0400
commit918690f9811029667eaf132dbfeb180c6e4e2029 (patch)
tree7bcefc7484e88090eba789b3b6a52e17a83a2f55 /net
parent31111c26d976ca0f298312f08e44cdb078005b03 (diff)
parent106af2c99a5249b809aaed45b8353ac087821f4a (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c21
-rw-r--r--net/mac80211/chan.c3
-rw-r--r--net/mac80211/driver-ops.h26
-rw-r--r--net/mac80211/driver-trace.h52
-rw-r--r--net/mac80211/mlme.c37
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c41
-rw-r--r--net/wireless/ethtool.c33
7 files changed, 201 insertions, 12 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 7b701dcddb50..334213571ad0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -834,6 +834,10 @@ static int ieee80211_change_station(struct wiphy *wiphy,
834 834
835 rcu_read_unlock(); 835 rcu_read_unlock();
836 836
837 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
838 params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))
839 ieee80211_recalc_ps(local, -1);
840
837 return 0; 841 return 0;
838} 842}
839 843
@@ -2008,6 +2012,21 @@ static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
2008 return drv_get_antenna(local, tx_ant, rx_ant); 2012 return drv_get_antenna(local, tx_ant, rx_ant);
2009} 2013}
2010 2014
2015static int ieee80211_set_ringparam(struct wiphy *wiphy, u32 tx, u32 rx)
2016{
2017 struct ieee80211_local *local = wiphy_priv(wiphy);
2018
2019 return drv_set_ringparam(local, tx, rx);
2020}
2021
2022static void ieee80211_get_ringparam(struct wiphy *wiphy,
2023 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
2024{
2025 struct ieee80211_local *local = wiphy_priv(wiphy);
2026
2027 drv_get_ringparam(local, tx, tx_max, rx, rx_max);
2028}
2029
2011struct cfg80211_ops mac80211_config_ops = { 2030struct cfg80211_ops mac80211_config_ops = {
2012 .add_virtual_intf = ieee80211_add_iface, 2031 .add_virtual_intf = ieee80211_add_iface,
2013 .del_virtual_intf = ieee80211_del_iface, 2032 .del_virtual_intf = ieee80211_del_iface,
@@ -2065,4 +2084,6 @@ struct cfg80211_ops mac80211_config_ops = {
2065 .mgmt_frame_register = ieee80211_mgmt_frame_register, 2084 .mgmt_frame_register = ieee80211_mgmt_frame_register,
2066 .set_antenna = ieee80211_set_antenna, 2085 .set_antenna = ieee80211_set_antenna,
2067 .get_antenna = ieee80211_get_antenna, 2086 .get_antenna = ieee80211_get_antenna,
2087 .set_ringparam = ieee80211_set_ringparam,
2088 .get_ringparam = ieee80211_get_ringparam,
2068}; 2089};
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 5b24740fc0b0..889c3e93e0f4 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -77,6 +77,9 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
77 switch (tmp->vif.bss_conf.channel_type) { 77 switch (tmp->vif.bss_conf.channel_type) {
78 case NL80211_CHAN_NO_HT: 78 case NL80211_CHAN_NO_HT:
79 case NL80211_CHAN_HT20: 79 case NL80211_CHAN_HT20:
80 if (superchan > tmp->vif.bss_conf.channel_type)
81 break;
82
80 superchan = tmp->vif.bss_conf.channel_type; 83 superchan = tmp->vif.bss_conf.channel_type;
81 break; 84 break;
82 case NL80211_CHAN_HT40PLUS: 85 case NL80211_CHAN_HT40PLUS:
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 3729296f6f95..9c0d62bb0ea3 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -526,4 +526,30 @@ static inline int drv_offchannel_tx_cancel_wait(struct ieee80211_local *local)
526 return ret; 526 return ret;
527} 527}
528 528
529static inline int drv_set_ringparam(struct ieee80211_local *local,
530 u32 tx, u32 rx)
531{
532 int ret = -ENOTSUPP;
533
534 might_sleep();
535
536 trace_drv_set_ringparam(local, tx, rx);
537 if (local->ops->set_ringparam)
538 ret = local->ops->set_ringparam(&local->hw, tx, rx);
539 trace_drv_return_int(local, ret);
540
541 return ret;
542}
543
544static inline void drv_get_ringparam(struct ieee80211_local *local,
545 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
546{
547 might_sleep();
548
549 trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
550 if (local->ops->get_ringparam)
551 local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
552 trace_drv_return_void(local);
553}
554
529#endif /* __MAC80211_DRIVER_OPS */ 555#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 520fe2444893..45aab80738e2 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -912,6 +912,58 @@ TRACE_EVENT(drv_offchannel_tx,
912 ) 912 )
913); 913);
914 914
915TRACE_EVENT(drv_set_ringparam,
916 TP_PROTO(struct ieee80211_local *local, u32 tx, u32 rx),
917
918 TP_ARGS(local, tx, rx),
919
920 TP_STRUCT__entry(
921 LOCAL_ENTRY
922 __field(u32, tx)
923 __field(u32, rx)
924 ),
925
926 TP_fast_assign(
927 LOCAL_ASSIGN;
928 __entry->tx = tx;
929 __entry->rx = rx;
930 ),
931
932 TP_printk(
933 LOCAL_PR_FMT " tx:%d rx %d",
934 LOCAL_PR_ARG, __entry->tx, __entry->rx
935 )
936);
937
938TRACE_EVENT(drv_get_ringparam,
939 TP_PROTO(struct ieee80211_local *local, u32 *tx, u32 *tx_max,
940 u32 *rx, u32 *rx_max),
941
942 TP_ARGS(local, tx, tx_max, rx, rx_max),
943
944 TP_STRUCT__entry(
945 LOCAL_ENTRY
946 __field(u32, tx)
947 __field(u32, tx_max)
948 __field(u32, rx)
949 __field(u32, rx_max)
950 ),
951
952 TP_fast_assign(
953 LOCAL_ASSIGN;
954 __entry->tx = *tx;
955 __entry->tx_max = *tx_max;
956 __entry->rx = *rx;
957 __entry->rx_max = *rx_max;
958 ),
959
960 TP_printk(
961 LOCAL_PR_FMT " tx:%d tx_max %d rx %d rx_max %d",
962 LOCAL_PR_ARG,
963 __entry->tx, __entry->tx_max, __entry->rx, __entry->rx_max
964 )
965);
966
915DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait, 967DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait,
916 TP_PROTO(struct ieee80211_local *local), 968 TP_PROTO(struct ieee80211_local *local),
917 TP_ARGS(local) 969 TP_ARGS(local)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cc984bd861cf..64d92d5a7f40 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -613,6 +613,37 @@ static void ieee80211_change_ps(struct ieee80211_local *local)
613 } 613 }
614} 614}
615 615
616static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
617{
618 struct ieee80211_if_managed *mgd = &sdata->u.mgd;
619 struct sta_info *sta = NULL;
620 u32 sta_flags = 0;
621
622 if (!mgd->powersave)
623 return false;
624
625 if (!mgd->associated)
626 return false;
627
628 if (!mgd->associated->beacon_ies)
629 return false;
630
631 if (mgd->flags & (IEEE80211_STA_BEACON_POLL |
632 IEEE80211_STA_CONNECTION_POLL))
633 return false;
634
635 rcu_read_lock();
636 sta = sta_info_get(sdata, mgd->bssid);
637 if (sta)
638 sta_flags = get_sta_flags(sta);
639 rcu_read_unlock();
640
641 if (!(sta_flags & WLAN_STA_AUTHORIZED))
642 return false;
643
644 return true;
645}
646
616/* need to hold RTNL or interface lock */ 647/* need to hold RTNL or interface lock */
617void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) 648void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
618{ 649{
@@ -647,11 +678,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
647 count++; 678 count++;
648 } 679 }
649 680
650 if (count == 1 && found->u.mgd.powersave && 681 if (count == 1 && ieee80211_powersave_allowed(found)) {
651 found->u.mgd.associated &&
652 found->u.mgd.associated->beacon_ies &&
653 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
654 IEEE80211_STA_CONNECTION_POLL))) {
655 struct ieee80211_conf *conf = &local->hw.conf; 682 struct ieee80211_conf *conf = &local->hw.conf;
656 s32 beaconint_us; 683 s32 beaconint_us;
657 684
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index bce14fbfc3b6..8212a8bebf06 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -598,19 +598,46 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
598 sample = true; 598 sample = true;
599 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, 599 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx,
600 txrc, true, false); 600 txrc, true, false);
601 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate,
602 txrc, false, false);
603 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 601 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
604 } else { 602 } else {
605 minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, 603 minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate,
606 txrc, false, false); 604 txrc, false, false);
607 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2,
608 txrc, false, true);
609 } 605 }
610 minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, !sample);
611 606
612 ar[3].count = 0; 607 if (mp->hw->max_rates >= 3) {
613 ar[3].idx = -1; 608 /*
609 * At least 3 tx rates supported, use
610 * sample_rate -> max_tp_rate -> max_prob_rate for sampling and
611 * max_tp_rate -> max_tp_rate2 -> max_prob_rate by default.
612 */
613 if (sample_idx >= 0)
614 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate,
615 txrc, false, false);
616 else
617 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2,
618 txrc, false, true);
619
620 minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate,
621 txrc, false, !sample);
622
623 ar[3].count = 0;
624 ar[3].idx = -1;
625 } else if (mp->hw->max_rates == 2) {
626 /*
627 * Only 2 tx rates supported, use
628 * sample_rate -> max_prob_rate for sampling and
629 * max_tp_rate -> max_prob_rate by default.
630 */
631 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_prob_rate,
632 txrc, false, !sample);
633
634 ar[2].count = 0;
635 ar[2].idx = -1;
636 } else {
637 /* Not using MRR, only use the first rate */
638 ar[1].count = 0;
639 ar[1].idx = -1;
640 }
614 641
615 mi->total_packets++; 642 mi->total_packets++;
616 643
diff --git a/net/wireless/ethtool.c b/net/wireless/ethtool.c
index ca4c825be93d..9bde4d1d3e9b 100644
--- a/net/wireless/ethtool.c
+++ b/net/wireless/ethtool.c
@@ -1,5 +1,6 @@
1#include <linux/utsname.h> 1#include <linux/utsname.h>
2#include <net/cfg80211.h> 2#include <net/cfg80211.h>
3#include "core.h"
3#include "ethtool.h" 4#include "ethtool.h"
4 5
5static void cfg80211_get_drvinfo(struct net_device *dev, 6static void cfg80211_get_drvinfo(struct net_device *dev,
@@ -37,9 +38,41 @@ static void cfg80211_get_regs(struct net_device *dev, struct ethtool_regs *regs,
37 regs->len = 0; 38 regs->len = 0;
38} 39}
39 40
41static void cfg80211_get_ringparam(struct net_device *dev,
42 struct ethtool_ringparam *rp)
43{
44 struct wireless_dev *wdev = dev->ieee80211_ptr;
45 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
46
47 memset(rp, 0, sizeof(*rp));
48
49 if (rdev->ops->get_ringparam)
50 rdev->ops->get_ringparam(wdev->wiphy,
51 &rp->tx_pending, &rp->tx_max_pending,
52 &rp->rx_pending, &rp->rx_max_pending);
53}
54
55static int cfg80211_set_ringparam(struct net_device *dev,
56 struct ethtool_ringparam *rp)
57{
58 struct wireless_dev *wdev = dev->ieee80211_ptr;
59 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
60
61 if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0)
62 return -EINVAL;
63
64 if (rdev->ops->set_ringparam)
65 return rdev->ops->set_ringparam(wdev->wiphy,
66 rp->tx_pending, rp->rx_pending);
67
68 return -ENOTSUPP;
69}
70
40const struct ethtool_ops cfg80211_ethtool_ops = { 71const struct ethtool_ops cfg80211_ethtool_ops = {
41 .get_drvinfo = cfg80211_get_drvinfo, 72 .get_drvinfo = cfg80211_get_drvinfo,
42 .get_regs_len = cfg80211_get_regs_len, 73 .get_regs_len = cfg80211_get_regs_len,
43 .get_regs = cfg80211_get_regs, 74 .get_regs = cfg80211_get_regs,
44 .get_link = ethtool_op_get_link, 75 .get_link = ethtool_op_get_link,
76 .get_ringparam = cfg80211_get_ringparam,
77 .set_ringparam = cfg80211_set_ringparam,
45}; 78};