Commit 6cd4fa5a authored by Ajay Singh's avatar Ajay Singh Committed by Greg Kroah-Hartman

staging: wilc1000: make use of cfg80211_inform_bss_frame()

Use cfg80211_inform_bss_frame() api instead of cfg80211_inform_bss() to
inform cfg80211 about the BSS frame, to avoid unnecessary parsing of
frame in driver.
Signed-off-by: default avatarAjay Singh <ajay.kathat@microchip.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6c2cfb4e
...@@ -72,7 +72,7 @@ struct wilc_gtk_key { ...@@ -72,7 +72,7 @@ struct wilc_gtk_key {
} __packed; } __packed;
union message_body { union message_body {
struct rcvd_net_info net_info; struct wilc_rcvd_net_info net_info;
struct rcvd_async_info async_info; struct rcvd_async_info async_info;
struct set_multicast multicast_info; struct set_multicast multicast_info;
struct remain_ch remain_on_ch; struct remain_ch remain_on_ch;
...@@ -743,129 +743,38 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss) ...@@ -743,129 +743,38 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss)
return (void *)param; return (void *)param;
} }
static inline u8 *get_bssid(struct ieee80211_mgmt *mgmt) static void handle_rcvd_ntwrk_info(struct work_struct *work)
{
if (ieee80211_has_fromds(mgmt->frame_control))
return mgmt->sa;
else if (ieee80211_has_tods(mgmt->frame_control))
return mgmt->da;
else
return mgmt->bssid;
}
static s32 wilc_parse_network_info(u8 *msg_buffer,
struct network_info **ret_network_info)
{ {
struct network_info *info; struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
struct ieee80211_mgmt *mgt; struct wilc_rcvd_net_info *rcvd_info = &msg->body.net_info;
u8 *wid_val, *ies; struct user_scan_req *scan_req = &msg->vif->hif_drv->usr_scan_req;
u16 wid_len, rx_len, ies_len; const u8 *ch_elm;
u8 msg_type; u8 *ies;
int ies_len;
size_t offset; size_t offset;
const u8 *ch_elm, *tim_elm, *ssid_elm;
msg_type = msg_buffer[0];
if ('N' != msg_type)
return -EFAULT;
wid_len = get_unaligned_le16(&msg_buffer[6]);
wid_val = &msg_buffer[8];
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->rssi = wid_val[0];
mgt = (struct ieee80211_mgmt *)&wid_val[1]; if (ieee80211_is_probe_resp(rcvd_info->mgmt->frame_control))
rx_len = wid_len - 1;
if (ieee80211_is_probe_resp(mgt->frame_control)) {
info->cap_info = le16_to_cpu(mgt->u.probe_resp.capab_info);
info->beacon_period = le16_to_cpu(mgt->u.probe_resp.beacon_int);
info->tsf = le64_to_cpu(mgt->u.probe_resp.timestamp);
info->tsf_lo = (u32)info->tsf;
offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
} else if (ieee80211_is_beacon(mgt->frame_control)) { else if (ieee80211_is_beacon(rcvd_info->mgmt->frame_control))
info->cap_info = le16_to_cpu(mgt->u.beacon.capab_info);
info->beacon_period = le16_to_cpu(mgt->u.beacon.beacon_int);
info->tsf = le64_to_cpu(mgt->u.beacon.timestamp);
info->tsf_lo = (u32)info->tsf;
offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
} else {
/* only process probe response and beacon frame */
kfree(info);
return -EIO;
}
ether_addr_copy(info->bssid, get_bssid(mgt));
ies = mgt->u.beacon.variable;
ies_len = rx_len - offset;
if (ies_len <= 0) {
kfree(info);
return -EIO;
}
info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
if (!info->ies) {
kfree(info);
return -ENOMEM;
}
info->ies_len = ies_len;
ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len);
if (ssid_elm) {
info->ssid_len = ssid_elm[1];
if (info->ssid_len <= IEEE80211_MAX_SSID_LEN)
memcpy(info->ssid, ssid_elm + 2, info->ssid_len);
else else
info->ssid_len = 0;
}
ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len);
if (ch_elm && ch_elm[1] > 0)
info->ch = ch_elm[2];
tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len);
if (tim_elm && tim_elm[1] >= 2)
info->dtim_period = tim_elm[3];
*ret_network_info = info;
return 0;
}
static void handle_rcvd_ntwrk_info(struct work_struct *work)
{
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
struct wilc_vif *vif = msg->vif;
struct rcvd_net_info *rcvd_info = &msg->body.net_info;
struct network_info *info = NULL;
struct user_scan_req *scan_req = &vif->hif_drv->usr_scan_req;
if (!scan_req->scan_result)
goto done; goto done;
wilc_parse_network_info(rcvd_info->buffer, &info); ies = rcvd_info->mgmt->u.beacon.variable;
if (!info) { ies_len = rcvd_info->frame_len - offset;
netdev_err(vif->ndev, "%s: info is NULL\n", if (ies_len <= 0)
__func__);
goto done; goto done;
}
scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, info, scan_req->arg); ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len);
if (ch_elm && ch_elm[1] > 0)
done: rcvd_info->ch = ch_elm[2];
kfree(rcvd_info->buffer);
rcvd_info->buffer = NULL;
if (info) { if (scan_req->scan_result)
kfree(info->ies); scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, rcvd_info,
kfree(info); scan_req->arg);
}
done:
kfree(rcvd_info->mgmt);
kfree(msg); kfree(msg);
} }
...@@ -2143,9 +2052,12 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) ...@@ -2143,9 +2052,12 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
if (IS_ERR(msg)) if (IS_ERR(msg))
return; return;
msg->body.net_info.len = length; msg->body.net_info.frame_len = get_unaligned_le16(&buffer[6]) - 1;
msg->body.net_info.buffer = kmemdup(buffer, length, GFP_KERNEL); msg->body.net_info.rssi = buffer[8];
if (!msg->body.net_info.buffer) { msg->body.net_info.mgmt = kmemdup(&buffer[9],
msg->body.net_info.frame_len,
GFP_KERNEL);
if (!msg->body.net_info.mgmt) {
kfree(msg); kfree(msg);
return; return;
} }
...@@ -2153,7 +2065,7 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length) ...@@ -2153,7 +2065,7 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
result = wilc_enqueue_work(msg); result = wilc_enqueue_work(msg);
if (result) { if (result) {
netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__); netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
kfree(msg->body.net_info.buffer); kfree(msg->body.net_info.mgmt);
kfree(msg); kfree(msg);
} }
} }
......
...@@ -127,7 +127,14 @@ enum conn_event { ...@@ -127,7 +127,14 @@ enum conn_event {
CONN_DISCONN_EVENT_FORCE_32BIT = 0xFFFFFFFF CONN_DISCONN_EVENT_FORCE_32BIT = 0xFFFFFFFF
}; };
typedef void (*wilc_scan_result)(enum scan_event, struct network_info *, struct wilc_rcvd_net_info {
s8 rssi;
u8 ch;
u16 frame_len;
struct ieee80211_mgmt *mgmt;
};
typedef void (*wilc_scan_result)(enum scan_event, struct wilc_rcvd_net_info *,
void *); void *);
typedef void (*wilc_connect_result)(enum conn_event, typedef void (*wilc_connect_result)(enum conn_event,
...@@ -139,11 +146,6 @@ typedef void (*wilc_connect_result)(enum conn_event, ...@@ -139,11 +146,6 @@ typedef void (*wilc_connect_result)(enum conn_event,
typedef void (*wilc_remain_on_chan_expired)(void *, u32); typedef void (*wilc_remain_on_chan_expired)(void *, u32);
typedef void (*wilc_remain_on_chan_ready)(void *); typedef void (*wilc_remain_on_chan_ready)(void *);
struct rcvd_net_info {
u8 *buffer;
u32 len;
};
struct hidden_net_info { struct hidden_net_info {
u8 *ssid; u8 *ssid;
u8 ssid_len; u8 ssid_len;
......
...@@ -82,47 +82,33 @@ static void clear_during_ip(struct timer_list *t) ...@@ -82,47 +82,33 @@ static void clear_during_ip(struct timer_list *t)
} }
static void cfg_scan_result(enum scan_event scan_event, static void cfg_scan_result(enum scan_event scan_event,
struct network_info *network_info, struct wilc_rcvd_net_info *info, void *user_void)
void *user_void)
{ {
struct wilc_priv *priv; struct wilc_priv *priv = user_void;
struct wiphy *wiphy;
s32 freq;
struct ieee80211_channel *channel;
struct cfg80211_bss *bss;
priv = user_void;
if (!priv->cfg_scanning) if (!priv->cfg_scanning)
return; return;
if (scan_event == SCAN_EVENT_NETWORK_FOUND) { if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
wiphy = priv->dev->ieee80211_ptr->wiphy; s32 freq;
struct ieee80211_channel *channel;
if (!wiphy || !network_info) struct cfg80211_bss *bss;
return; struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && if (!wiphy || !info)
(((s32)network_info->rssi * 100) < 0 ||
((s32)network_info->rssi * 100) > 100))
return; return;
freq = ieee80211_channel_to_frequency((s32)network_info->ch, freq = ieee80211_channel_to_frequency((s32)info->ch,
NL80211_BAND_2GHZ); NL80211_BAND_2GHZ);
channel = ieee80211_get_channel(wiphy, freq); channel = ieee80211_get_channel(wiphy, freq);
if (!channel) if (!channel)
return; return;
bss = cfg80211_inform_bss(wiphy, bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt,
channel, info->frame_len,
CFG80211_BSS_FTYPE_UNKNOWN, (s32)info->rssi * 100,
network_info->bssid,
network_info->tsf,
network_info->cap_info,
network_info->beacon_period,
(const u8 *)network_info->ies,
(size_t)network_info->ies_len,
(s32)network_info->rssi * 100,
GFP_KERNEL); GFP_KERNEL);
if (!bss)
cfg80211_put_bss(wiphy, bss); cfg80211_put_bss(wiphy, bss);
} else if (scan_event == SCAN_EVENT_DONE) { } else if (scan_event == SCAN_EVENT_DONE) {
mutex_lock(&priv->scan_req_lock); mutex_lock(&priv->scan_req_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment