Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 737be10d authored by John W. Linville's avatar John W. Linville
Browse files
parents 03c44446 d3a58df8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1711,6 +1711,7 @@ enum ieee80211_eid {
	WLAN_EID_RRM_ENABLED_CAPABILITIES = 70,
	WLAN_EID_MULTIPLE_BSSID = 71,
	WLAN_EID_BSS_COEX_2040 = 72,
	WLAN_EID_BSS_INTOLERANT_CHL_REPORT = 73,
	WLAN_EID_OVERLAP_BSS_SCAN_PARAM = 74,
	WLAN_EID_RIC_DESCRIPTOR = 75,
	WLAN_EID_MMIE = 76,
+46 −0
Original line number Diff line number Diff line
@@ -188,6 +188,43 @@ struct ieee80211_chanctx_conf {
	u8 drv_priv[0] __aligned(sizeof(void *));
};

/**
 * enum ieee80211_chanctx_switch_mode - channel context switch mode
 * @CHANCTX_SWMODE_REASSIGN_VIF: Both old and new contexts already
 *	exist (and will continue to exist), but the virtual interface
 *	needs to be switched from one to the other.
 * @CHANCTX_SWMODE_SWAP_CONTEXTS: The old context exists but will stop
 *      to exist with this call, the new context doesn't exist but
 *      will be active after this call, the virtual interface switches
 *      from the old to the new (note that the driver may of course
 *      implement this as an on-the-fly chandef switch of the existing
 *      hardware context, but the mac80211 pointer for the old context
 *      will cease to exist and only the new one will later be used
 *      for changes/removal.)
 */
enum ieee80211_chanctx_switch_mode {
	CHANCTX_SWMODE_REASSIGN_VIF,
	CHANCTX_SWMODE_SWAP_CONTEXTS,
};

/**
 * struct ieee80211_vif_chanctx_switch - vif chanctx switch information
 *
 * This is structure is used to pass information about a vif that
 * needs to switch from one chanctx to another.  The
 * &ieee80211_chanctx_switch_mode defines how the switch should be
 * done.
 *
 * @vif: the vif that should be switched from old_ctx to new_ctx
 * @old_ctx: the old context to which the vif was assigned
 * @new_ctx: the new context to which the vif must be assigned
 */
struct ieee80211_vif_chanctx_switch {
	struct ieee80211_vif *vif;
	struct ieee80211_chanctx_conf *old_ctx;
	struct ieee80211_chanctx_conf *new_ctx;
};

/**
 * enum ieee80211_bss_change - BSS change notification flags
 *
@@ -2736,6 +2773,11 @@ enum ieee80211_roc_type {
 *	to vif. Possible use is for hw queue remapping.
 * @unassign_vif_chanctx: Notifies device driver about channel context being
 *	unbound from vif.
 * @switch_vif_chanctx: switch a number of vifs from one chanctx to
 *	another, as specified in the list of
 *	@ieee80211_vif_chanctx_switch passed to the driver, according
 *	to the mode defined in &ieee80211_chanctx_switch_mode.
 *
 * @start_ap: Start operation on the AP interface, this is called after all the
 *	information in bss_conf is set and beacon can be retrieved. A channel
 *	context is bound before this is called. Note that if the driver uses
@@ -2952,6 +2994,10 @@ struct ieee80211_ops {
	void (*unassign_vif_chanctx)(struct ieee80211_hw *hw,
				     struct ieee80211_vif *vif,
				     struct ieee80211_chanctx_conf *ctx);
	int (*switch_vif_chanctx)(struct ieee80211_hw *hw,
				  struct ieee80211_vif_chanctx_switch *vifs,
				  int n_vifs,
				  enum ieee80211_chanctx_switch_mode mode);

	void (*restart_complete)(struct ieee80211_hw *hw);

+2 −4
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ static ssize_t ieee80211_if_read(
	ssize_t ret = -EINVAL;

	read_lock(&dev_base_lock);
	if (sdata->dev->reg_state == NETREG_REGISTERED)
	ret = (*format)(sdata, buf, sizeof(buf));
	read_unlock(&dev_base_lock);

@@ -62,7 +61,6 @@ static ssize_t ieee80211_if_write(

	ret = -ENODEV;
	rtnl_lock();
	if (sdata->dev->reg_state == NETREG_REGISTERED)
	ret = (*write)(sdata, buf, count);
	rtnl_unlock();

+53 −0
Original line number Diff line number Diff line
@@ -1048,6 +1048,59 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
	trace_drv_return_void(local);
}

static inline int
drv_switch_vif_chanctx(struct ieee80211_local *local,
		       struct ieee80211_vif_chanctx_switch *vifs,
		       int n_vifs,
		       enum ieee80211_chanctx_switch_mode mode)
{
	int ret = 0;
	int i;

	if (!local->ops->switch_vif_chanctx)
		return -EOPNOTSUPP;

	for (i = 0; i < n_vifs; i++) {
		struct ieee80211_chanctx *new_ctx =
			container_of(vifs[i].new_ctx,
				     struct ieee80211_chanctx,
				     conf);
		struct ieee80211_chanctx *old_ctx =
			container_of(vifs[i].old_ctx,
				     struct ieee80211_chanctx,
				     conf);

		WARN_ON_ONCE(!old_ctx->driver_present);
		WARN_ON_ONCE((mode == CHANCTX_SWMODE_SWAP_CONTEXTS &&
			      new_ctx->driver_present) ||
			     (mode == CHANCTX_SWMODE_REASSIGN_VIF &&
			      !new_ctx->driver_present));
	}

	trace_drv_switch_vif_chanctx(local, vifs, n_vifs, mode);
	ret = local->ops->switch_vif_chanctx(&local->hw,
					     vifs, n_vifs, mode);
	trace_drv_return_int(local, ret);

	if (!ret && mode == CHANCTX_SWMODE_SWAP_CONTEXTS) {
		for (i = 0; i < n_vifs; i++) {
			struct ieee80211_chanctx *new_ctx =
				container_of(vifs[i].new_ctx,
					     struct ieee80211_chanctx,
					     conf);
			struct ieee80211_chanctx *old_ctx =
				container_of(vifs[i].old_ctx,
					     struct ieee80211_chanctx,
					     conf);

			new_ctx->driver_present = true;
			old_ctx->driver_present = false;
		}
	}

	return ret;
}

static inline int drv_start_ap(struct ieee80211_local *local,
			       struct ieee80211_sub_if_data *sdata)
{
+1 −0
Original line number Diff line number Diff line
@@ -1677,6 +1677,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
	sdata->u.ibss.control_port = params->control_port;
	sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs;
	sdata->u.ibss.basic_rates = params->basic_rates;
	sdata->u.ibss.last_scan_completed = jiffies;

	/* fix basic_rates if channel does not support these rates */
	rate_flags = ieee80211_chandef_rate_flags(&params->chandef);
Loading