Message ID | 1389345563-3445-1-git-send-email-michal.kazior@tieto.com (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Michal Kazior <michal.kazior@tieto.com> writes: > This patch implements Channel Switch Announcement > for AP mode. This allows for a smooth channel > switch for connected stations that support CSA > when radar is detected. > > Signed-off-by: Michal Kazior <michal.kazior@tieto.com> I had few conflicts while applying to ath-next-test (the branch for pending patches). Please double check my changes: https://github.com/kvalo/ath/commit/c7bb77f4bf9986e6be4b522ba1e01cd78ebb66af
On 10 January 2014 11:22, Kalle Valo <kvalo@qca.qualcomm.com> wrote: > Michal Kazior <michal.kazior@tieto.com> writes: > >> This patch implements Channel Switch Announcement >> for AP mode. This allows for a smooth channel >> switch for connected stations that support CSA >> when radar is detected. >> >> Signed-off-by: Michal Kazior <michal.kazior@tieto.com> > > I had few conflicts while applying to ath-next-test (the branch for > pending patches). Please double check my changes: > > https://github.com/kvalo/ath/commit/c7bb77f4bf9986e6be4b522ba1e01cd78ebb66af It looks good, thanks. Micha? -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Michal Kazior <michal.kazior@tieto.com> writes: > This patch implements Channel Switch Announcement > for AP mode. This allows for a smooth channel > switch for connected stations that support CSA > when radar is detected. > > Signed-off-by: Michal Kazior <michal.kazior@tieto.com> [...] > --- a/drivers/net/wireless/ath/ath10k/core.h > +++ b/drivers/net/wireless/ath/ath10k/core.h > @@ -414,6 +414,7 @@ struct ath10k { > unsigned int filter_flags; > unsigned long dev_flags; > u32 dfs_block_radar_events; > + struct ath10k_vif *csa_arvif; Please document how this is serialised. > +static void ath10k_mac_update_ap_channel(struct ath10k_vif *arvif) > +{ Please change this function to return the error code. > + const u8 *bssid = arvif->vif->bss_conf.bssid; > + int ret; > + > + ath10k_dbg(ATH10K_DBG_MAC, "mac AP channel update %dMHz\n", > + arvif->ar->hw->conf.chandef.chan->center_freq); > + > + ret = ath10k_vdev_stop(arvif); > + if (ret) { > + ath10k_warn("could not stop vdev %d (%d)\n", > + arvif->vdev_id, ret); > + return; > + } > + > + ret = ath10k_vdev_start(arvif); > + if (ret) { > + ath10k_warn("could not start vdev %d (%d)\n", > + arvif->vdev_id, ret); > + return; > + } > + > + ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, 0, bssid); > + if (ret) { > + ath10k_warn("could not bring vdev up %d (%d)\n", > + arvif->vdev_id, ret); > + return; > + } For warning and error messages please use style: "could not bring vdev up %d: %d\n" > @@ -2156,6 +2185,9 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) > spin_unlock_bh(&ar->data_lock); > > ath10k_config_radar_detection(ar); > + > + if (ar->csa_arvif && ar->csa_arvif->vif->csa_active) > + ath10k_mac_update_ap_channel(ar->csa_arvif); Check the error message here, print a warning and return if there's an error. But should we return 0 or the error code, that I do not know. > --- a/drivers/net/wireless/ath/ath10k/wmi.c > +++ b/drivers/net/wireless/ath/ath10k/wmi.c > @@ -558,6 +558,22 @@ err_pull: > return ret; > } > > +static void ath10k_update_csa(struct ath10k_vif *arvif) > +{ > + lockdep_assert_held(&arvif->ar->data_lock); > + > + if (arvif->ar->csa_arvif != arvif) > + return; > + > + if (!arvif->vif->csa_active) > + return; > + > + if (!ieee80211_csa_is_complete(arvif->vif)) > + return; > + > + ieee80211_csa_finish(arvif->vif); > +} For consistency I would prefer that all functions return an error code, but I guess that would not make any sense here. Does it?
On 17 January 2014 13:57, Kalle Valo <kvalo@qca.qualcomm.com> wrote: > Michal Kazior <michal.kazior@tieto.com> writes: > >> This patch implements Channel Switch Announcement >> for AP mode. This allows for a smooth channel >> switch for connected stations that support CSA >> when radar is detected. >> >> Signed-off-by: Michal Kazior <michal.kazior@tieto.com> > > [...] > >> --- a/drivers/net/wireless/ath/ath10k/core.h >> +++ b/drivers/net/wireless/ath/ath10k/core.h >> @@ -414,6 +414,7 @@ struct ath10k { >> unsigned int filter_flags; >> unsigned long dev_flags; >> u32 dfs_block_radar_events; >> + struct ath10k_vif *csa_arvif; > > Please document how this is serialised. [...] I have a local patch capable of multi-interface CSA which basically rewrites this patch entirely. Unless you want me send that as a follow up patch later I'd like to drop this patch and send a completely new one later. Micha? -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Michal Kazior <michal.kazior@tieto.com> writes: > On 17 January 2014 13:57, Kalle Valo <kvalo@qca.qualcomm.com> wrote: >> Michal Kazior <michal.kazior@tieto.com> writes: >> >>> This patch implements Channel Switch Announcement >>> for AP mode. This allows for a smooth channel >>> switch for connected stations that support CSA >>> when radar is detected. >>> >>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com> >> >> [...] >> >>> --- a/drivers/net/wireless/ath/ath10k/core.h >>> +++ b/drivers/net/wireless/ath/ath10k/core.h >>> @@ -414,6 +414,7 @@ struct ath10k { >>> unsigned int filter_flags; >>> unsigned long dev_flags; >>> u32 dfs_block_radar_events; >>> + struct ath10k_vif *csa_arvif; >> >> Please document how this is serialised. > > [...] > > I have a local patch capable of multi-interface CSA which basically > rewrites this patch entirely. Unless you want me send that as a follow > up patch later I'd like to drop this patch and send a completely new > one later. Yeah, let's then just drop this patch.
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 035cbf6..2554161 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -414,6 +414,7 @@ struct ath10k { unsigned int filter_flags; unsigned long dev_flags; u32 dfs_block_radar_events; + struct ath10k_vif *csa_arvif; struct wmi_pdev_set_wmm_params_arg wmm_params; struct completion install_key_done; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 5b45f3a..5c26766 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -435,8 +435,7 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar) static int ath10k_vdev_start(struct ath10k_vif *arvif) { struct ath10k *ar = arvif->ar; - struct ieee80211_conf *conf = &ar->hw->conf; - struct ieee80211_channel *channel = conf->chandef.chan; + struct cfg80211_chan_def *chandef = &ar->hw->conf.chandef; struct wmi_vdev_start_request_arg arg = {}; int ret = 0; @@ -448,16 +447,14 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) arg.dtim_period = arvif->dtim_period; arg.bcn_intval = arvif->beacon_interval; - arg.channel.freq = channel->center_freq; - - arg.channel.band_center_freq1 = conf->chandef.center_freq1; - - arg.channel.mode = chan_to_phymode(&conf->chandef); + arg.channel.freq = chandef->chan->center_freq; + arg.channel.band_center_freq1 = chandef->center_freq1; + arg.channel.mode = chan_to_phymode(chandef); arg.channel.min_power = 0; - arg.channel.max_power = channel->max_power * 2; - arg.channel.max_reg_power = channel->max_reg_power * 2; - arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; + arg.channel.max_power = chandef->chan->max_power * 2; + arg.channel.max_reg_power = chandef->chan->max_reg_power * 2; + arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2; if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { arg.ssid = arvif->u.ap.ssid; @@ -466,7 +463,7 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) /* For now allow DFS for AP mode */ arg.channel.chan_radar = - !!(channel->flags & IEEE80211_CHAN_RADAR); + !!(chandef->chan->flags & IEEE80211_CHAN_RADAR); } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) { arg.ssid = arvif->vif->bss_conf.ssid; arg.ssid_len = arvif->vif->bss_conf.ssid_len; @@ -2136,6 +2133,38 @@ static int ath10k_config_ps(struct ath10k *ar) return ret; } +static void ath10k_mac_update_ap_channel(struct ath10k_vif *arvif) +{ + const u8 *bssid = arvif->vif->bss_conf.bssid; + int ret; + + ath10k_dbg(ATH10K_DBG_MAC, "mac AP channel update %dMHz\n", + arvif->ar->hw->conf.chandef.chan->center_freq); + + ret = ath10k_vdev_stop(arvif); + if (ret) { + ath10k_warn("could not stop vdev %d (%d)\n", + arvif->vdev_id, ret); + return; + } + + ret = ath10k_vdev_start(arvif); + if (ret) { + ath10k_warn("could not start vdev %d (%d)\n", + arvif->vdev_id, ret); + return; + } + + ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, 0, bssid); + if (ret) { + ath10k_warn("could not bring vdev up %d (%d)\n", + arvif->vdev_id, ret); + return; + } + + ath10k_dbg(ATH10K_DBG_MAC, "mac AP channel update complete\n"); +} + static int ath10k_config(struct ieee80211_hw *hw, u32 changed) { struct ath10k *ar = hw->priv; @@ -2156,6 +2185,9 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) spin_unlock_bh(&ar->data_lock); ath10k_config_radar_detection(ar); + + if (ar->csa_arvif && ar->csa_arvif->vif->csa_active) + ath10k_mac_update_ap_channel(ar->csa_arvif); } if (changed & IEEE80211_CONF_CHANGE_POWER) { @@ -2495,6 +2527,12 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, "vdev %d set beacon tx mode to staggered\n", arvif->vdev_id); + if (ar->csa_arvif) { + ath10k_dbg(ATH10K_DBG_MAC, "mac CSA completed for vdev_id %d\n", + arvif->vdev_id); + ar->csa_arvif = NULL; + } + pdev_param = ar->wmi.pdev_param->beacon_tx_mode; ret = ath10k_wmi_pdev_set_param(ar, pdev_param, WMI_BEACON_STAGGERED_MODE); @@ -3310,6 +3348,24 @@ exit: return ret; } +static void ath10k_channel_switch_beacon(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_chan_def *chandef) +{ + struct ath10k *ar = hw->priv; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + + /* FIXME: Multi-VIF not supported */ + + if (ar->csa_arvif != NULL) { + ath10k_warn("CSA is already active for this device, ignoring!\n"); + return; + } + + ar->csa_arvif = arvif; + return; +} + static const struct ieee80211_ops ath10k_ops = { .tx = ath10k_tx, .start = ath10k_start, @@ -3332,6 +3388,7 @@ static const struct ieee80211_ops ath10k_ops = { .tx_last_beacon = ath10k_tx_last_beacon, .restart_complete = ath10k_restart_complete, .get_survey = ath10k_get_survey, + .channel_switch_beacon = ath10k_channel_switch_beacon, #ifdef CONFIG_PM .suspend = ath10k_suspend, .resume = ath10k_resume, @@ -3712,6 +3769,7 @@ int ath10k_mac_register(struct ath10k *ar) ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL; ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; ar->hw->wiphy->max_remain_on_channel_duration = 5000; ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 3ec6c9a..5985197 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -558,6 +558,22 @@ err_pull: return ret; } +static void ath10k_update_csa(struct ath10k_vif *arvif) +{ + lockdep_assert_held(&arvif->ar->data_lock); + + if (arvif->ar->csa_arvif != arvif) + return; + + if (!arvif->vif->csa_active) + return; + + if (!ieee80211_csa_is_complete(arvif->vif)) + return; + + ieee80211_csa_finish(arvif->vif); +} + static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif) { struct wmi_bcn_tx_arg arg = {0}; @@ -580,6 +596,8 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif) dev_kfree_skb_any(arvif->beacon); arvif->beacon = NULL; + + ath10k_update_csa(arvif); } static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac,
This patch implements Channel Switch Announcement for AP mode. This allows for a smooth channel switch for connected stations that support CSA when radar is detected. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> --- drivers/net/wireless/ath/ath10k/core.h | 1 + drivers/net/wireless/ath/ath10k/mac.c | 80 +++++++++++++++++++++++++++++----- drivers/net/wireless/ath/ath10k/wmi.c | 18 ++++++++ 3 files changed, 88 insertions(+), 11 deletions(-)