From 7a62f643c0e816fd444f0d951bb008c89bbc36cf Mon Sep 17 00:00:00 2001 From: Ajay Singh Date: Thu, 1 Nov 2018 16:45:05 +0000 Subject: [PATCH] staging: wilc1000: refactor wilc_parse_network_info() using kernel framework api's Refactor wilc_parse_network_info() by making use of cfg80211.h provided API. Signed-off-by: Ajay Singh Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/coreconfigurator.c | 90 +++++++++++++-------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index d6d3a971be43..4dfa658198cf 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -4,7 +4,7 @@ * All rights reserved. */ -#include +#include #include "coreconfigurator.h" @@ -116,11 +116,11 @@ static inline void get_address3(u8 *msa, u8 *addr) memcpy(addr, msa + 16, 6); } -static inline void get_bssid(u8 *data, u8 *bssid) +static inline void get_bssid(__le16 fc, u8 *data, u8 *bssid) { - if (get_from_ds(data) == 1) + if (ieee80211_has_fromds(fc)) get_address2(data, bssid); - else if (get_to_ds(data) == 1) + else if (ieee80211_has_tods(fc)) get_address1(data, bssid); else get_address3(data, bssid); @@ -202,17 +202,18 @@ s32 wilc_parse_network_info(u8 *msg_buffer, struct network_info **ret_network_info) { struct network_info *network_info; - u8 *wid_val, *msa, *tim_elm, *ies; - u32 tsf_lo, tsf_hi; + struct ieee80211_mgmt *mgt; + u8 *wid_val, *msa, *ies; u16 wid_len, rx_len, ies_len; - u8 msg_type, index; + u8 msg_type; + size_t offset; + const u8 *ch_elm, *tim_elm, *ssid_elm; msg_type = msg_buffer[0]; - if ('N' != msg_type) return -EFAULT; - wid_len = MAKE_WORD16(msg_buffer[6], msg_buffer[7]); + wid_len = get_unaligned_le16(&msg_buffer[6]); wid_val = &msg_buffer[8]; network_info = kzalloc(sizeof(*network_info), GFP_KERNEL); @@ -222,42 +223,61 @@ s32 wilc_parse_network_info(u8 *msg_buffer, network_info->rssi = wid_val[0]; msa = &wid_val[1]; - + mgt = (struct ieee80211_mgmt *)&wid_val[1]; rx_len = wid_len - 1; - network_info->cap_info = get_cap_info(msa); - network_info->tsf_lo = get_beacon_timestamp_lo(msa); - tsf_lo = get_beacon_timestamp_lo(msa); - tsf_hi = get_beacon_timestamp_hi(msa); + if (ieee80211_is_probe_resp(mgt->frame_control)) { + network_info->cap_info = le16_to_cpu(mgt->u.probe_resp.capab_info); + network_info->beacon_period = le16_to_cpu(mgt->u.probe_resp.beacon_int); + network_info->tsf_hi = le64_to_cpu(mgt->u.probe_resp.timestamp); + network_info->tsf_lo = (u32)network_info->tsf_hi; + offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); + } else if (ieee80211_is_beacon(mgt->frame_control)) { + network_info->cap_info = le16_to_cpu(mgt->u.beacon.capab_info); + network_info->beacon_period = le16_to_cpu(mgt->u.beacon.beacon_int); + network_info->tsf_hi = le64_to_cpu(mgt->u.beacon.timestamp); + network_info->tsf_lo = (u32)network_info->tsf_hi; + offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); + } else { + /* only process probe response and beacon frame */ + kfree(network_info); + return -EIO; + } - network_info->tsf_hi = tsf_lo | ((u64)tsf_hi << 32); + get_bssid(mgt->frame_control, msa, network_info->bssid); - get_ssid(msa, network_info->ssid, &network_info->ssid_len); - get_bssid(msa, network_info->bssid); + ies = mgt->u.beacon.variable; + ies_len = rx_len - offset; + if (ies_len <= 0) { + kfree(network_info); + return -EIO; + } - network_info->ch = get_current_channel_802_11n(msa, rx_len - + FCS_LEN); + network_info->ies = kmemdup(ies, ies_len, GFP_KERNEL); + if (!network_info->ies) { + kfree(network_info); + return -ENOMEM; + } - index = MAC_HDR_LEN + TIME_STAMP_LEN; + network_info->ies_len = ies_len; - network_info->beacon_period = get_beacon_period(msa + index); + ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len); + if (ssid_elm) { + network_info->ssid_len = ssid_elm[1]; + if (network_info->ssid_len <= IEEE80211_MAX_SSID_LEN) + memcpy(network_info->ssid, ssid_elm + 2, + network_info->ssid_len); + else + network_info->ssid_len = 0; + } - index += BEACON_INTERVAL_LEN + CAP_INFO_LEN; + ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len); + if (ch_elm && ch_elm[1] > 0) + network_info->ch = ch_elm[2]; - tim_elm = get_tim_elm(msa, rx_len + FCS_LEN, index); - if (tim_elm) + tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len); + if (tim_elm && tim_elm[1] >= 2) network_info->dtim_period = tim_elm[3]; - ies = &msa[TAG_PARAM_OFFSET]; - ies_len = rx_len - TAG_PARAM_OFFSET; - - if (ies_len > 0) { - network_info->ies = kmemdup(ies, ies_len, GFP_KERNEL); - if (!network_info->ies) { - kfree(network_info); - return -ENOMEM; - } - } - network_info->ies_len = ies_len; *ret_network_info = network_info; -- 2.30.2