Commit 830513ab authored by Eliad Peller's avatar Eliad Peller Committed by Kalle Valo

wlcore: add dfs master restart calls

call wlcore_cmd_dfs_master_restart when starting
the ap on a new channel (after csa is done).

Add a new WLVIF_FLAG_BEACON_DISABLED flag to
indicate that dfs_master_restart command
is required.
Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 534719f4
...@@ -229,3 +229,28 @@ int wl18xx_cmd_radar_detection_debug(struct wl1271 *wl, u8 channel) ...@@ -229,3 +229,28 @@ int wl18xx_cmd_radar_detection_debug(struct wl1271 *wl, u8 channel)
kfree(cmd); kfree(cmd);
return ret; return ret;
} }
int wl18xx_cmd_dfs_master_restart(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{
struct wl18xx_cmd_dfs_master_restart *cmd;
int ret = 0;
wl1271_debug(DEBUG_CMD, "cmd dfs master restart (role %d)",
wlvif->role_id);
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd)
return -ENOMEM;
cmd->role_id = wlvif->role_id;
ret = wl1271_cmd_send(wl, CMD_DFS_MASTER_RESTART,
cmd, sizeof(*cmd), 0);
if (ret < 0) {
wl1271_error("failed to send dfs master restart command");
goto out_free;
}
out_free:
kfree(cmd);
return ret;
}
...@@ -66,6 +66,13 @@ struct wl18xx_cmd_dfs_radar_debug { ...@@ -66,6 +66,13 @@ struct wl18xx_cmd_dfs_radar_debug {
u8 padding[3]; u8 padding[3];
} __packed; } __packed;
struct wl18xx_cmd_dfs_master_restart {
struct wl1271_cmd_header header;
u8 role_id;
u8 padding[3];
} __packed;
/* cac_start and cac_stop share the same params */ /* cac_start and cac_stop share the same params */
struct wlcore_cmd_cac_start { struct wlcore_cmd_cac_start {
struct wl1271_cmd_header header; struct wl1271_cmd_header header;
...@@ -85,4 +92,5 @@ int wl18xx_cmd_smart_config_set_group_key(struct wl1271 *wl, u16 group_id, ...@@ -85,4 +92,5 @@ int wl18xx_cmd_smart_config_set_group_key(struct wl1271 *wl, u16 group_id,
u8 key_len, u8 *key); u8 key_len, u8 *key);
int wl18xx_cmd_set_cac(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool start); int wl18xx_cmd_set_cac(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool start);
int wl18xx_cmd_radar_detection_debug(struct wl1271 *wl, u8 channel); int wl18xx_cmd_radar_detection_debug(struct wl1271 *wl, u8 channel);
int wl18xx_cmd_dfs_master_restart(struct wl1271 *wl, struct wl12xx_vif *wlvif);
#endif #endif
...@@ -1705,6 +1705,7 @@ static struct wlcore_ops wl18xx_ops = { ...@@ -1705,6 +1705,7 @@ static struct wlcore_ops wl18xx_ops = {
.rx_ba_filter = wl18xx_acx_rx_ba_filter, .rx_ba_filter = wl18xx_acx_rx_ba_filter,
.ap_sleep = wl18xx_acx_ap_sleep, .ap_sleep = wl18xx_acx_ap_sleep,
.set_cac = wl18xx_cmd_set_cac, .set_cac = wl18xx_cmd_set_cac,
.dfs_master_restart = wl18xx_cmd_dfs_master_restart,
}; };
/* HT cap appropriate for wide channels in 2Ghz */ /* HT cap appropriate for wide channels in 2Ghz */
......
...@@ -154,6 +154,7 @@ void wlcore_event_channel_switch(struct wl1271 *wl, ...@@ -154,6 +154,7 @@ void wlcore_event_channel_switch(struct wl1271 *wl,
ieee80211_chswitch_done(vif, success); ieee80211_chswitch_done(vif, success);
cancel_delayed_work(&wlvif->channel_switch_work); cancel_delayed_work(&wlvif->channel_switch_work);
} else { } else {
set_bit(WLVIF_FLAG_BEACON_DISABLED, &wlvif->flags);
ieee80211_csa_finish(vif); ieee80211_csa_finish(vif);
} }
} }
......
...@@ -320,4 +320,13 @@ wlcore_hw_set_cac(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool start) ...@@ -320,4 +320,13 @@ wlcore_hw_set_cac(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool start)
return wl->ops->set_cac(wl, wlvif, start); return wl->ops->set_cac(wl, wlvif, start);
} }
static inline int
wlcore_hw_dfs_master_restart(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{
if (!wl->ops->dfs_master_restart)
return -EINVAL;
return wl->ops->dfs_master_restart(wl, wlvif);
}
#endif #endif
...@@ -4127,8 +4127,14 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, ...@@ -4127,8 +4127,14 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
ret = wlcore_set_beacon_template(wl, vif, is_ap); ret = wlcore_set_beacon_template(wl, vif, is_ap);
if (ret < 0) if (ret < 0)
goto out; goto out;
}
if (test_and_clear_bit(WLVIF_FLAG_BEACON_DISABLED,
&wlvif->flags)) {
ret = wlcore_hw_dfs_master_restart(wl, wlvif);
if (ret < 0)
goto out;
}
}
out: out:
if (ret != 0) if (ret != 0)
wl1271_error("beacon info change failed: %d", ret); wl1271_error("beacon info change failed: %d", ret);
...@@ -4774,6 +4780,8 @@ static int __wlcore_switch_vif_chan(struct wl1271 *wl, ...@@ -4774,6 +4780,8 @@ static int __wlcore_switch_vif_chan(struct wl1271 *wl,
if (WARN_ON_ONCE(wlvif->bss_type != BSS_TYPE_AP_BSS)) if (WARN_ON_ONCE(wlvif->bss_type != BSS_TYPE_AP_BSS))
return 0; return 0;
WARN_ON(!test_bit(WLVIF_FLAG_BEACON_DISABLED, &wlvif->flags));
if (wlvif->radar_enabled) { if (wlvif->radar_enabled) {
wl1271_debug(DEBUG_MAC80211, "Stop radar detection"); wl1271_debug(DEBUG_MAC80211, "Stop radar detection");
wlcore_hw_set_cac(wl, wlvif, false); wlcore_hw_set_cac(wl, wlvif, false);
......
...@@ -125,6 +125,7 @@ struct wlcore_ops { ...@@ -125,6 +125,7 @@ struct wlcore_ops {
u8 key_len, u8 *key); u8 key_len, u8 *key);
int (*set_cac)(struct wl1271 *wl, struct wl12xx_vif *wlvif, int (*set_cac)(struct wl1271 *wl, struct wl12xx_vif *wlvif,
bool start); bool start);
int (*dfs_master_restart)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
}; };
enum wlcore_partitions { enum wlcore_partitions {
......
...@@ -251,6 +251,7 @@ enum wl12xx_vif_flags { ...@@ -251,6 +251,7 @@ enum wl12xx_vif_flags {
WLVIF_FLAG_AP_PROBE_RESP_SET, WLVIF_FLAG_AP_PROBE_RESP_SET,
WLVIF_FLAG_IN_USE, WLVIF_FLAG_IN_USE,
WLVIF_FLAG_ACTIVE, WLVIF_FLAG_ACTIVE,
WLVIF_FLAG_BEACON_DISABLED,
}; };
struct wl12xx_vif; struct wl12xx_vif;
......
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