diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 62 |
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 | ||
1971 | static 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 | |||
1996 | nla_put_failure: | ||
1997 | return false; | ||
1998 | } | ||
1999 | |||
1971 | static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, | 2000 | static 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 | ||
3002 | nla_put_failure: | 3021 | nla_put_failure: |
3003 | genlmsg_cancel(msg, hdr); | 3022 | genlmsg_cancel(msg, hdr); |
3023 | put_failure: | ||
3004 | nlmsg_free(msg); | 3024 | nlmsg_free(msg); |
3005 | err = -EMSGSIZE; | 3025 | err = -EMSGSIZE; |
3006 | out: | 3026 | out: |