staging: wilc1000: handle add and edit station from the cfg80211 context

Refactor the code to avoid handling of add/edit stations using work
queue and now set the wid value from caller context.
Avoid making an extra copy of buffer and directly copy the data in
firmware expected format.

Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Ajay Singh 2018-12-02 18:02:34 +00:00 committed by Greg Kroah-Hartman
parent cf6d06002d
commit 78c0c4e845
3 changed files with 64 additions and 164 deletions

View File

@ -121,9 +121,7 @@ union message_body {
struct cfg_param_attr cfg_info;
struct channel_attr channel_info;
struct beacon_attr beacon_info;
struct add_sta_param add_sta_info;
struct del_sta del_sta_info;
struct add_sta_param edit_sta_info;
struct sta_inactive_t mac_info;
struct set_ip_addr ip_info;
struct drv_handler drv;
@ -1962,67 +1960,41 @@ static void handle_del_beacon(struct work_struct *work)
kfree(msg);
}
static u32 wilc_hif_pack_sta_param(u8 *buff, struct add_sta_param *param)
static u32 wilc_hif_pack_sta_param(u8 *buff, const u8 *mac,
struct station_parameters *params)
{
u8 *cur_byte;
cur_byte = buff;
ether_addr_copy(cur_byte, mac);
cur_byte += ETH_ALEN;
memcpy(cur_byte, param->bssid, ETH_ALEN);
cur_byte += ETH_ALEN;
put_unaligned_le16(params->aid, cur_byte);
cur_byte += 2;
*cur_byte++ = param->aid & 0xFF;
*cur_byte++ = (param->aid >> 8) & 0xFF;
*cur_byte++ = params->supported_rates_len;
if (params->supported_rates_len > 0)
memcpy(cur_byte, params->supported_rates,
params->supported_rates_len);
cur_byte += params->supported_rates_len;
*cur_byte++ = param->rates_len;
if (param->rates_len > 0)
memcpy(cur_byte, param->rates, param->rates_len);
cur_byte += param->rates_len;
*cur_byte++ = param->ht_supported;
memcpy(cur_byte, &param->ht_capa, sizeof(struct ieee80211_ht_cap));
if (params->ht_capa) {
*cur_byte++ = true;
memcpy(cur_byte, &params->ht_capa,
sizeof(struct ieee80211_ht_cap));
} else {
*cur_byte++ = false;
}
cur_byte += sizeof(struct ieee80211_ht_cap);
*cur_byte++ = param->flags_mask & 0xFF;
*cur_byte++ = (param->flags_mask >> 8) & 0xFF;
*cur_byte++ = param->flags_set & 0xFF;
*cur_byte++ = (param->flags_set >> 8) & 0xFF;
put_unaligned_le16(params->sta_flags_mask, cur_byte);
cur_byte += 2;
put_unaligned_le16(params->sta_flags_set, cur_byte);
cur_byte += 2;
return cur_byte - buff;
}
static void handle_add_station(struct work_struct *work)
{
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
struct wilc_vif *vif = msg->vif;
struct add_sta_param *param = &msg->body.add_sta_info;
int result;
struct wid wid;
u8 *cur_byte;
wid.id = WID_ADD_STA;
wid.type = WID_BIN;
wid.size = WILC_ADD_STA_LENGTH + param->rates_len;
wid.val = kmalloc(wid.size, GFP_KERNEL);
if (!wid.val)
goto error;
cur_byte = wid.val;
cur_byte += wilc_hif_pack_sta_param(cur_byte, param);
result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
wilc_get_vif_idx(vif));
if (result != 0)
netdev_err(vif->ndev, "Failed to send add station\n");
error:
kfree(param->rates);
kfree(wid.val);
kfree(msg);
}
static void handle_del_all_sta(struct work_struct *work)
{
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
@ -2095,37 +2067,6 @@ error:
kfree(msg);
}
static void handle_edit_station(struct work_struct *work)
{
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
struct wilc_vif *vif = msg->vif;
struct add_sta_param *param = &msg->body.edit_sta_info;
int result;
struct wid wid;
u8 *cur_byte;
wid.id = WID_EDIT_STA;
wid.type = WID_BIN;
wid.size = WILC_ADD_STA_LENGTH + param->rates_len;
wid.val = kmalloc(wid.size, GFP_KERNEL);
if (!wid.val)
goto error;
cur_byte = wid.val;
cur_byte += wilc_hif_pack_sta_param(cur_byte, param);
result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
wilc_get_vif_idx(vif));
if (result)
netdev_err(vif->ndev, "Failed to send edit station\n");
error:
kfree(param->rates);
kfree(wid.val);
kfree(msg);
}
static int handle_remain_on_chan(struct wilc_vif *vif,
struct remain_ch *hif_remain_ch)
{
@ -3484,34 +3425,30 @@ int wilc_del_beacon(struct wilc_vif *vif)
return result;
}
int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
struct station_parameters *params)
{
struct wid wid;
int result;
struct host_if_msg *msg;
struct add_sta_param *add_sta_info;
u8 *cur_byte;
msg = wilc_alloc_work(vif, handle_add_station, false);
if (IS_ERR(msg))
return PTR_ERR(msg);
wid.id = WID_ADD_STA;
wid.type = WID_BIN;
wid.size = WILC_ADD_STA_LENGTH + params->supported_rates_len;
wid.val = kmalloc(wid.size, GFP_KERNEL);
if (!wid.val)
return -ENOMEM;
add_sta_info = &msg->body.add_sta_info;
memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
if (add_sta_info->rates_len > 0) {
add_sta_info->rates = kmemdup(sta_param->rates,
add_sta_info->rates_len,
GFP_KERNEL);
if (!add_sta_info->rates) {
kfree(msg);
return -ENOMEM;
}
}
cur_byte = wid.val;
cur_byte += wilc_hif_pack_sta_param(cur_byte, mac, params);
result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
wilc_get_vif_idx(vif));
if (result != 0)
netdev_err(vif->ndev, "Failed to send add station\n");
kfree(wid.val);
result = wilc_enqueue_work(msg);
if (result) {
netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
kfree(add_sta_info->rates);
kfree(msg);
}
return result;
}
@ -3580,36 +3517,29 @@ int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
return result;
}
int wilc_edit_station(struct wilc_vif *vif,
struct add_sta_param *sta_param)
int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
struct station_parameters *params)
{
struct wid wid;
int result;
struct host_if_msg *msg;
struct add_sta_param *add_sta_info;
u8 *cur_byte;
msg = wilc_alloc_work(vif, handle_edit_station, false);
if (IS_ERR(msg))
return PTR_ERR(msg);
wid.id = WID_EDIT_STA;
wid.type = WID_BIN;
wid.size = WILC_ADD_STA_LENGTH + params->supported_rates_len;
wid.val = kmalloc(wid.size, GFP_KERNEL);
if (!wid.val)
return -ENOMEM;
add_sta_info = &msg->body.add_sta_info;
memcpy(add_sta_info, sta_param, sizeof(*add_sta_info));
if (add_sta_info->rates_len > 0) {
add_sta_info->rates = kmemdup(sta_param->rates,
add_sta_info->rates_len,
GFP_KERNEL);
if (!add_sta_info->rates) {
kfree(msg);
return -ENOMEM;
}
}
cur_byte = wid.val;
cur_byte += wilc_hif_pack_sta_param(cur_byte, mac, params);
result = wilc_enqueue_work(msg);
if (result) {
netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
kfree(add_sta_info->rates);
kfree(msg);
}
result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
wilc_get_vif_idx(vif));
if (result)
netdev_err(vif->ndev, "Failed to send edit station\n");
kfree(wid.val);
return result;
}

View File

@ -326,11 +326,12 @@ int wilc_deinit(struct wilc_vif *vif);
int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
u32 head_len, u8 *head, u32 tail_len, u8 *tail);
int wilc_del_beacon(struct wilc_vif *vif);
int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param);
int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
struct station_parameters *params);
int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN]);
int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr);
int wilc_edit_station(struct wilc_vif *vif,
struct add_sta_param *sta_param);
int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
struct station_parameters *params);
int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout);
int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count,
u8 *mc_list);

View File

@ -1818,28 +1818,13 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev,
{
int ret = 0;
struct wilc_priv *priv = wiphy_priv(wiphy);
struct add_sta_param sta_params = { {0} };
struct wilc_vif *vif = netdev_priv(dev);
if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
memcpy(sta_params.bssid, mac, ETH_ALEN);
memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
ETH_ALEN);
sta_params.aid = params->aid;
sta_params.rates_len = params->supported_rates_len;
sta_params.rates = params->supported_rates;
if (!params->ht_capa) {
sta_params.ht_supported = false;
} else {
sta_params.ht_supported = true;
sta_params.ht_capa = *params->ht_capa;
}
sta_params.flags_mask = params->sta_flags_mask;
sta_params.flags_set = params->sta_flags_set;
ret = wilc_add_station(vif, &sta_params);
ret = wilc_add_station(vif, mac, params);
if (ret)
netdev_err(dev, "Host add station fail\n");
}
@ -1874,26 +1859,10 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev,
const u8 *mac, struct station_parameters *params)
{
int ret = 0;
struct add_sta_param sta_params = { {0} };
struct wilc_vif *vif = netdev_priv(dev);
if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
memcpy(sta_params.bssid, mac, ETH_ALEN);
sta_params.aid = params->aid;
sta_params.rates_len = params->supported_rates_len;
sta_params.rates = params->supported_rates;
if (!params->ht_capa) {
sta_params.ht_supported = false;
} else {
sta_params.ht_supported = true;
sta_params.ht_capa = *params->ht_capa;
}
sta_params.flags_mask = params->sta_flags_mask;
sta_params.flags_set = params->sta_flags_set;
ret = wilc_edit_station(vif, &sta_params);
ret = wilc_edit_station(vif, mac, params);
if (ret)
netdev_err(dev, "Host edit station fail\n");
}