@@ -4762,7 +4762,8 @@ struct cfg80211_ops {
int (*channel_switch)(struct wiphy *wiphy,
struct net_device *dev,
- struct cfg80211_csa_settings *params);
+ struct cfg80211_csa_settings *params,
+ unsigned int link_id);
int (*set_qos_map)(struct wiphy *wiphy,
struct net_device *dev,
@@ -3844,7 +3844,8 @@ static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata)
static int
__ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_csa_settings *params)
+ struct cfg80211_csa_settings *params,
+ unsigned int link_id)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
@@ -3856,6 +3857,9 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
lockdep_assert_wiphy(local->hw.wiphy);
+ if (WARN_ON(link_id > IEEE80211_MLD_MAX_NUM_LINKS))
+ return -EINVAL;
+
if (!list_empty(&local->roc_list) || local->scanning)
return -EBUSY;
@@ -3949,14 +3953,15 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
}
int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_csa_settings *params)
+ struct cfg80211_csa_settings *params,
+ unsigned int link_id)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
lockdep_assert_wiphy(local->hw.wiphy);
- return __ieee80211_channel_switch(wiphy, dev, params);
+ return __ieee80211_channel_switch(wiphy, dev, params, link_id);
}
u64 ieee80211_mgmt_tx_cookie(struct ieee80211_local *local)
@@ -871,7 +871,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
params.block_tx = !!csa_ie.mode;
if (ieee80211_channel_switch(sdata->local->hw.wiphy, sdata->dev,
- ¶ms))
+ ¶ms, 0))
goto disconnect;
ieee80211_ibss_csa_mark_radar(sdata);
@@ -1947,7 +1947,8 @@ int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
/* channel switch handling */
void ieee80211_csa_finalize_work(struct wiphy *wiphy, struct wiphy_work *work);
int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_csa_settings *params);
+ struct cfg80211_csa_settings *params,
+ unsigned int link_id);
/* color change handling */
void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
@@ -1391,7 +1391,7 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_REPEATER;
if (ieee80211_channel_switch(sdata->local->hw.wiphy, sdata->dev,
- ¶ms) < 0)
+ ¶ms, 0) < 0)
return false;
return true;
@@ -10240,7 +10240,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
goto free;
}
- err = rdev_channel_switch(rdev, dev, ¶ms);
+ err = rdev_channel_switch(rdev, dev, ¶ms, link_id);
free:
kfree(params.beacon_after.mbssid_ies);
@@ -1099,12 +1099,13 @@ static inline void rdev_crit_proto_stop(struct cfg80211_registered_device *rdev,
static inline int rdev_channel_switch(struct cfg80211_registered_device *rdev,
struct net_device *dev,
- struct cfg80211_csa_settings *params)
+ struct cfg80211_csa_settings *params,
+ unsigned int link_id)
{
int ret;
- trace_rdev_channel_switch(&rdev->wiphy, dev, params);
- ret = rdev->ops->channel_switch(&rdev->wiphy, dev, params);
+ trace_rdev_channel_switch(&rdev->wiphy, dev, params, link_id);
+ ret = rdev->ops->channel_switch(&rdev->wiphy, dev, params, link_id);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
@@ -2311,8 +2311,9 @@ TRACE_EVENT(rdev_crit_proto_stop,
TRACE_EVENT(rdev_channel_switch,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
- struct cfg80211_csa_settings *params),
- TP_ARGS(wiphy, netdev, params),
+ struct cfg80211_csa_settings *params,
+ unsigned int link_id),
+ TP_ARGS(wiphy, netdev, params, link_id),
TP_STRUCT__entry(
WIPHY_ENTRY
NETDEV_ENTRY
@@ -2322,6 +2323,7 @@ TRACE_EVENT(rdev_channel_switch,
__field(u8, count)
__dynamic_array(u16, bcn_ofs, params->n_counter_offsets_beacon)
__dynamic_array(u16, pres_ofs, params->n_counter_offsets_presp)
+ __field(unsigned int, link_id)
),
TP_fast_assign(
WIPHY_ASSIGN;
@@ -2339,11 +2341,13 @@ TRACE_EVENT(rdev_channel_switch,
memcpy(__get_dynamic_array(pres_ofs),
params->counter_offsets_presp,
params->n_counter_offsets_presp * sizeof(u16));
+ __entry->link_id = link_id;
),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT
- ", block_tx: %d, count: %u, radar_required: %d",
+ ", block_tx: %d, count: %u, radar_required: %d link_id: %d",
WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG,
- __entry->block_tx, __entry->count, __entry->radar_required)
+ __entry->block_tx, __entry->count, __entry->radar_required,
+ __entry->link_id)
);
TRACE_EVENT(rdev_set_qos_map,
Currently, during channel switch, no link id information is passed due to which channel switch is carried on deflink always. In order to support channel switch during Multi Link Operation, it is required to pass link id as well. Add changes to pass link id in the channel_switch cfg80211_ops. Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com> --- include/net/cfg80211.h | 3 ++- net/mac80211/cfg.c | 11 ++++++++--- net/mac80211/ibss.c | 2 +- net/mac80211/ieee80211_i.h | 3 ++- net/mac80211/mesh.c | 2 +- net/wireless/nl80211.c | 2 +- net/wireless/rdev-ops.h | 7 ++++--- net/wireless/trace.h | 12 ++++++++---- 8 files changed, 27 insertions(+), 15 deletions(-)