diff options
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/scan.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 7f97a087f452..9596015975d2 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -771,6 +771,38 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
771 | return found; | 771 | return found; |
772 | } | 772 | } |
773 | 773 | ||
774 | static struct ieee80211_channel * | ||
775 | cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, | ||
776 | struct ieee80211_channel *channel) | ||
777 | { | ||
778 | const u8 *tmp; | ||
779 | u32 freq; | ||
780 | int channel_number = -1; | ||
781 | |||
782 | tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen); | ||
783 | if (tmp && tmp[1] == 1) { | ||
784 | channel_number = tmp[2]; | ||
785 | } else { | ||
786 | tmp = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie, ielen); | ||
787 | if (tmp && tmp[1] >= sizeof(struct ieee80211_ht_operation)) { | ||
788 | struct ieee80211_ht_operation *htop = (void *)(tmp + 2); | ||
789 | |||
790 | channel_number = htop->primary_chan; | ||
791 | } | ||
792 | } | ||
793 | |||
794 | if (channel_number < 0) | ||
795 | return channel; | ||
796 | |||
797 | freq = ieee80211_channel_to_frequency(channel_number, channel->band); | ||
798 | channel = ieee80211_get_channel(wiphy, freq); | ||
799 | if (!channel) | ||
800 | return NULL; | ||
801 | if (channel->flags & IEEE80211_CHAN_DISABLED) | ||
802 | return NULL; | ||
803 | return channel; | ||
804 | } | ||
805 | |||
774 | struct cfg80211_bss* | 806 | struct cfg80211_bss* |
775 | cfg80211_inform_bss(struct wiphy *wiphy, | 807 | cfg80211_inform_bss(struct wiphy *wiphy, |
776 | struct ieee80211_channel *channel, | 808 | struct ieee80211_channel *channel, |
@@ -790,6 +822,10 @@ cfg80211_inform_bss(struct wiphy *wiphy, | |||
790 | (signal < 0 || signal > 100))) | 822 | (signal < 0 || signal > 100))) |
791 | return NULL; | 823 | return NULL; |
792 | 824 | ||
825 | channel = cfg80211_get_bss_channel(wiphy, ie, ielen, channel); | ||
826 | if (!channel) | ||
827 | return NULL; | ||
828 | |||
793 | res = kzalloc(sizeof(*res) + privsz + ielen, gfp); | 829 | res = kzalloc(sizeof(*res) + privsz + ielen, gfp); |
794 | if (!res) | 830 | if (!res) |
795 | return NULL; | 831 | return NULL; |
@@ -839,11 +875,13 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
839 | s32 signal, gfp_t gfp) | 875 | s32 signal, gfp_t gfp) |
840 | { | 876 | { |
841 | struct cfg80211_internal_bss *res; | 877 | struct cfg80211_internal_bss *res; |
842 | |||
843 | size_t ielen = len - offsetof(struct ieee80211_mgmt, | 878 | size_t ielen = len - offsetof(struct ieee80211_mgmt, |
844 | u.probe_resp.variable); | 879 | u.probe_resp.variable); |
845 | size_t privsz; | 880 | size_t privsz; |
846 | 881 | ||
882 | BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != | ||
883 | offsetof(struct ieee80211_mgmt, u.beacon.variable)); | ||
884 | |||
847 | trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal); | 885 | trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal); |
848 | 886 | ||
849 | if (WARN_ON(!mgmt)) | 887 | if (WARN_ON(!mgmt)) |
@@ -861,6 +899,11 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
861 | 899 | ||
862 | privsz = wiphy->bss_priv_size; | 900 | privsz = wiphy->bss_priv_size; |
863 | 901 | ||
902 | channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable, | ||
903 | ielen, channel); | ||
904 | if (!channel) | ||
905 | return NULL; | ||
906 | |||
864 | res = kzalloc(sizeof(*res) + privsz + ielen, gfp); | 907 | res = kzalloc(sizeof(*res) + privsz + ielen, gfp); |
865 | if (!res) | 908 | if (!res) |
866 | return NULL; | 909 | return NULL; |