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: Eliad Peller <eliad@wizery.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
@@ -229,3 +229,28 @@ out_free:
|
|||||||
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 {
|
|||||||
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,
|
|||||||
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 = {
|
|||||||
.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,
|
|||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user