Skip to content

Commit

Permalink
wl12xx: add device role commands
Browse files Browse the repository at this point in the history
The device role is a special role used for rx and tx frames
prior to association (as the STA role can get packets only
from its associated bssid)

Since this role is required for the sta association process,
we enable it when a new sta interface is created.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
  • Loading branch information
Eliad Peller authored and Luciano Coelho committed Aug 22, 2011
1 parent b78b47e commit 04e8079
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
91 changes: 91 additions & 0 deletions drivers/net/wireless/wl12xx/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,97 @@ static void wl12xx_free_link(struct wl1271 *wl, u8 *hlid)
*hlid = WL12XX_INVALID_LINK_ID;
}

int wl12xx_cmd_role_start_dev(struct wl1271 *wl)
{
struct wl12xx_cmd_role_start *cmd;
int ret;

cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd) {
ret = -ENOMEM;
goto out;
}

wl1271_debug(DEBUG_CMD, "cmd role start dev %d", wl->dev_role_id);

cmd->role_id = wl->dev_role_id;
if (wl->band == IEEE80211_BAND_5GHZ)
cmd->band = WL12XX_BAND_5GHZ;
cmd->channel = wl->channel;

if (wl->dev_hlid == WL12XX_INVALID_LINK_ID) {
ret = wl12xx_allocate_link(wl, &wl->dev_hlid);
if (ret)
goto out_free;
}
cmd->device.hlid = wl->dev_hlid;
cmd->device.session = wl->session_counter;

wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d",
cmd->role_id, cmd->device.hlid, cmd->device.session);

ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
if (ret < 0) {
wl1271_error("failed to initiate cmd role enable");
goto err_hlid;
}

goto out_free;

err_hlid:
/* clear links on error */
__clear_bit(wl->dev_hlid, wl->links_map);
wl->dev_hlid = WL12XX_INVALID_LINK_ID;


out_free:
kfree(cmd);

out:
return ret;
}

int wl12xx_cmd_role_stop_dev(struct wl1271 *wl)
{
struct wl12xx_cmd_role_stop *cmd;
int ret;

if (WARN_ON(wl->dev_hlid == WL12XX_INVALID_LINK_ID))
return -EINVAL;

cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd) {
ret = -ENOMEM;
goto out;
}

wl1271_debug(DEBUG_CMD, "cmd role stop dev");

cmd->role_id = wl->dev_role_id;
cmd->disc_type = DISCONNECT_IMMEDIATE;
cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED);

ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
if (ret < 0) {
wl1271_error("failed to initiate cmd role stop");
goto out_free;
}

ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
if (ret < 0) {
wl1271_error("cmd role stop dev event completion error");
goto out_free;
}

wl12xx_free_link(wl, &wl->dev_hlid);

out_free:
kfree(cmd);

out:
return ret;
}

int wl12xx_cmd_role_start_sta(struct wl1271 *wl)
{
struct wl12xx_cmd_role_start *cmd;
Expand Down
25 changes: 24 additions & 1 deletion drivers/net/wireless/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1866,6 +1866,20 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
if (ret < 0)
goto power_off;

if (wl->bss_type == BSS_TYPE_STA_BSS) {
/*
* The device role is a special role used for
* rx and tx frames prior to association (as
* the STA role can get packets only from
* its associated bssid)
*/
ret = wl12xx_cmd_role_enable(wl,
WL1271_ROLE_DEVICE,
&wl->dev_role_id);
if (ret < 0)
goto irq_disable;
}

ret = wl12xx_cmd_role_enable(wl, role_type, &wl->role_id);
if (ret < 0)
goto irq_disable;
Expand Down Expand Up @@ -1965,6 +1979,12 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
if (ret < 0)
goto deinit;

if (wl->bss_type == BSS_TYPE_STA_BSS) {
ret = wl12xx_cmd_role_disable(wl, &wl->dev_role_id);
if (ret < 0)
goto deinit;
}

ret = wl12xx_cmd_role_disable(wl, &wl->role_id);
if (ret < 0)
goto deinit;
Expand All @@ -1973,6 +1993,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
}
deinit:
wl->sta_hlid = WL12XX_INVALID_LINK_ID;
wl->dev_hlid = WL12XX_INVALID_LINK_ID;

/*
* this must be before the cancel_work calls below, so that the work
Expand Down Expand Up @@ -2023,6 +2044,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
wl->ap_ps_map = 0;
wl->sched_scanning = false;
wl->role_id = WL12XX_INVALID_ROLE_ID;
wl->dev_role_id = WL12XX_INVALID_ROLE_ID;
memset(wl->roles_map, 0, sizeof(wl->roles_map));
memset(wl->links_map, 0, sizeof(wl->links_map));

Expand Down Expand Up @@ -4365,7 +4387,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl->tx_security_last_seq_lsb = 0;
wl->role_id = WL12XX_INVALID_ROLE_ID;
wl->sta_hlid = WL12XX_INVALID_LINK_ID;

wl->dev_role_id = WL12XX_INVALID_ROLE_ID;
wl->dev_hlid = WL12XX_INVALID_LINK_ID;
setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer,
(unsigned long) wl);
wl->fwlog_size = 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/wl12xx/wl12xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ struct wl1271 {
u8 ssid_len;
int channel;
u8 role_id;
u8 dev_role_id;
u8 sta_hlid;
u8 dev_hlid;

Expand Down

0 comments on commit 04e8079

Please sign in to comment.