aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c62
1 files changed, 41 insertions, 21 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9b62710891a2..4ebce4284e9d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1968,13 +1968,41 @@ static int parse_station_flags(struct genl_info *info,
1968 return 0; 1968 return 0;
1969} 1969}
1970 1970
1971static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
1972 int attr)
1973{
1974 struct nlattr *rate;
1975 u16 bitrate;
1976
1977 rate = nla_nest_start(msg, attr);
1978 if (!rate)
1979 goto nla_put_failure;
1980
1981 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
1982 bitrate = cfg80211_calculate_bitrate(info);
1983 if (bitrate > 0)
1984 NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
1985
1986 if (info->flags & RATE_INFO_FLAGS_MCS)
1987 NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS, info->mcs);
1988 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
1989 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
1990 if (info->flags & RATE_INFO_FLAGS_SHORT_GI)
1991 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
1992
1993 nla_nest_end(msg, rate);
1994 return true;
1995
1996nla_put_failure:
1997 return false;
1998}
1999
1971static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, 2000static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1972 int flags, struct net_device *dev, 2001 int flags, struct net_device *dev,
1973 const u8 *mac_addr, struct station_info *sinfo) 2002 const u8 *mac_addr, struct station_info *sinfo)
1974{ 2003{
1975 void *hdr; 2004 void *hdr;
1976 struct nlattr *sinfoattr, *txrate; 2005 struct nlattr *sinfoattr;
1977 u16 bitrate;
1978 2006
1979 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); 2007 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1980 if (!hdr) 2008 if (!hdr)
@@ -2013,24 +2041,14 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2013 NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, 2041 NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
2014 sinfo->signal_avg); 2042 sinfo->signal_avg);
2015 if (sinfo->filled & STATION_INFO_TX_BITRATE) { 2043 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
2016 txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE); 2044 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
2017 if (!txrate) 2045 NL80211_STA_INFO_TX_BITRATE))
2046 goto nla_put_failure;
2047 }
2048 if (sinfo->filled & STATION_INFO_RX_BITRATE) {
2049 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
2050 NL80211_STA_INFO_RX_BITRATE))
2018 goto nla_put_failure; 2051 goto nla_put_failure;
2019
2020 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
2021 bitrate = cfg80211_calculate_bitrate(&sinfo->txrate);
2022 if (bitrate > 0)
2023 NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
2024
2025 if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
2026 NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
2027 sinfo->txrate.mcs);
2028 if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
2029 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
2030 if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
2031 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
2032
2033 nla_nest_end(msg, txrate);
2034 } 2052 }
2035 if (sinfo->filled & STATION_INFO_RX_PACKETS) 2053 if (sinfo->filled & STATION_INFO_RX_PACKETS)
2036 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS, 2054 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS,
@@ -2718,7 +2736,7 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
2718 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 2736 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2719 NL80211_CMD_GET_MESH_CONFIG); 2737 NL80211_CMD_GET_MESH_CONFIG);
2720 if (!hdr) 2738 if (!hdr)
2721 goto nla_put_failure; 2739 goto out;
2722 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG); 2740 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
2723 if (!pinfoattr) 2741 if (!pinfoattr)
2724 goto nla_put_failure; 2742 goto nla_put_failure;
@@ -2759,6 +2777,7 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
2759 2777
2760 nla_put_failure: 2778 nla_put_failure:
2761 genlmsg_cancel(msg, hdr); 2779 genlmsg_cancel(msg, hdr);
2780 out:
2762 nlmsg_free(msg); 2781 nlmsg_free(msg);
2763 return -ENOBUFS; 2782 return -ENOBUFS;
2764} 2783}
@@ -2954,7 +2973,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
2954 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 2973 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2955 NL80211_CMD_GET_REG); 2974 NL80211_CMD_GET_REG);
2956 if (!hdr) 2975 if (!hdr)
2957 goto nla_put_failure; 2976 goto put_failure;
2958 2977
2959 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, 2978 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2,
2960 cfg80211_regdomain->alpha2); 2979 cfg80211_regdomain->alpha2);
@@ -3001,6 +3020,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
3001 3020
3002nla_put_failure: 3021nla_put_failure:
3003 genlmsg_cancel(msg, hdr); 3022 genlmsg_cancel(msg, hdr);
3023put_failure:
3004 nlmsg_free(msg); 3024 nlmsg_free(msg);
3005 err = -EMSGSIZE; 3025 err = -EMSGSIZE;
3006out: 3026out: