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

Commit 17e360fa authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "wil6210: multiple VIFs support for start/stop AP" into msm-4.14

parents b716c2c1 8620dc92
Loading
Loading
Loading
Loading
+32 −17
Original line number Diff line number Diff line
@@ -616,8 +616,9 @@ wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
	return ERR_PTR(rc);
}

int wil_vif_prepare_stop(struct wil6210_priv *wil, struct wil6210_vif *vif)
int wil_vif_prepare_stop(struct wil6210_vif *vif)
{
	struct wil6210_priv *wil = vif_to_wil(vif);
	struct wireless_dev *wdev = vif_to_wdev(vif);
	struct net_device *ndev;
	int rc;
@@ -633,6 +634,7 @@ int wil_vif_prepare_stop(struct wil6210_priv *wil, struct wil6210_vif *vif)
				 rc);
			/* continue */
		}
		wil_bcast_fini(vif);
		netif_carrier_off(ndev);
	}

@@ -665,7 +667,7 @@ static int wil_cfg80211_del_iface(struct wiphy *wiphy,
		return -EINVAL;
	}

	rc = wil_vif_prepare_stop(wil, vif);
	rc = wil_vif_prepare_stop(vif);
	if (rc)
		goto out;

@@ -686,6 +688,7 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
	struct wil6210_vif *vif = ndev_to_vif(ndev);
	struct wireless_dev *wdev = vif_to_wdev(vif);
	int rc;
	bool fw_reset = false;

	wil_dbg_misc(wil, "change_iface: type=%d\n", type);

@@ -700,7 +703,7 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
	/* do not reset FW when there are active VIFs,
	 * because it can cause significant disruption
	 */
	if (!wil_has_other_up_ifaces(wil, ndev) &&
	if (!wil_has_other_active_ifaces(wil, ndev, true, false) &&
	    netif_running(ndev) && !wil_is_recovery_blocked(wil)) {
		wil_dbg_misc(wil, "interface is up. resetting...\n");
		mutex_lock(&wil->mutex);
@@ -710,6 +713,7 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,

		if (rc)
			return rc;
		fw_reset = true;
	}

	switch (type) {
@@ -726,8 +730,9 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
		return -EOPNOTSUPP;
	}

	if (vif->mid != 0 && wil_has_up_ifaces(wil)) {
		wil_vif_prepare_stop(wil, vif);
	if (vif->mid != 0 && wil_has_active_ifaces(wil, true, false)) {
		if (!fw_reset)
			wil_vif_prepare_stop(vif);
		rc = wmi_port_delete(wil, vif->mid);
		if (rc)
			return rc;
@@ -1602,10 +1607,12 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,

	mutex_lock(&wil->mutex);

	if (!wil_has_other_active_ifaces(wil, ndev, true, false)) {
		__wil_down(wil);
		rc = __wil_up(wil);
		if (rc)
			goto out;
	}

	rc = wmi_set_ssid(vif, ssid_len, ssid);
	if (rc)
@@ -1621,6 +1628,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
	vif->pbss = pbss;

	netif_carrier_on(ndev);
	if (!wil_has_other_active_ifaces(wil, ndev, false, true))
		wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);

	rc = wmi_pcp_start(vif, bi, wmi_nettype, chan, hidden_ssid, is_go);
@@ -1637,6 +1645,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
	wmi_pcp_stop(vif);
err_pcp_start:
	netif_carrier_off(ndev);
	if (!wil_has_other_active_ifaces(wil, ndev, false, true))
		wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
out:
	mutex_unlock(&wil->mutex);
@@ -1742,20 +1751,26 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
{
	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
	struct wil6210_vif *vif = ndev_to_vif(ndev);
	bool last;

	wil_dbg_misc(wil, "stop_ap\n");
	wil_dbg_misc(wil, "stop_ap, mid=%d\n", vif->mid);

	netif_carrier_off(ndev);
	last = !wil_has_other_active_ifaces(wil, ndev, false, true);
	if (last) {
		wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
		wil_set_recovery_state(wil, fw_recovery_idle);

		set_bit(wil_status_resetting, wil->status);
	}

	mutex_lock(&wil->mutex);

	wmi_pcp_stop(vif);

	if (last)
		__wil_down(wil);
	else
		wil_bcast_fini(vif);

	mutex_unlock(&wil->mutex);

+13 −1
Original line number Diff line number Diff line
@@ -511,6 +511,18 @@ void wil_bcast_fini(struct wil6210_vif *vif)
	wil_vring_fini_tx(wil, ri);
}

void wil_bcast_fini_all(struct wil6210_priv *wil)
{
	int i;
	struct wil6210_vif *vif;

	for (i = 0; i < wil->max_vifs; i++) {
		vif = wil->vifs[i];
		if (vif)
			wil_bcast_fini(vif);
	}
}

int wil_priv_init(struct wil6210_priv *wil)
{
	uint i;
@@ -1216,7 +1228,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)

	cancel_work_sync(&vif->disconnect_worker);
	wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
	wil_bcast_fini(vif);
	wil_bcast_fini_all(wil);

	/* Disable device led before reset*/
	wmi_led_cfg(wil, false);
+12 −10
Original line number Diff line number Diff line
@@ -25,8 +25,8 @@ static bool alt_ifname; /* = false; */
module_param(alt_ifname, bool, 0444);
MODULE_PARM_DESC(alt_ifname, " use an alternate interface name wigigN instead of wlanN");

bool wil_has_other_up_ifaces(struct wil6210_priv *wil,
			     struct net_device *ndev)
bool wil_has_other_active_ifaces(struct wil6210_priv *wil,
				 struct net_device *ndev, bool up, bool ok)
{
	int i;
	struct wil6210_vif *vif;
@@ -36,7 +36,9 @@ bool wil_has_other_up_ifaces(struct wil6210_priv *wil,
		vif = wil->vifs[i];
		if (vif) {
			ndev_i = vif_to_ndev(vif);
			if (ndev_i != ndev && ndev_i->flags & IFF_UP)
			if (ndev_i != ndev)
				if ((up && (ndev_i->flags & IFF_UP)) ||
				    (ok && netif_carrier_ok(ndev_i)))
					return true;
		}
	}
@@ -44,9 +46,9 @@ bool wil_has_other_up_ifaces(struct wil6210_priv *wil,
	return false;
}

bool wil_has_up_ifaces(struct wil6210_priv *wil)
bool wil_has_active_ifaces(struct wil6210_priv *wil, bool up, bool ok)
{
	return wil_has_other_up_ifaces(wil, NULL);
	return wil_has_other_active_ifaces(wil, NULL, up, ok);
}

static int wil_open(struct net_device *ndev)
@@ -62,7 +64,7 @@ static int wil_open(struct net_device *ndev)
		return -EINVAL;
	}

	if (!wil_has_other_up_ifaces(wil, ndev)) {
	if (!wil_has_other_active_ifaces(wil, ndev, true, false)) {
		wil_dbg_misc(wil, "open, first iface\n");
		rc = wil_pm_runtime_get(wil);
		if (rc < 0)
@@ -83,7 +85,7 @@ static int wil_stop(struct net_device *ndev)

	wil_dbg_misc(wil, "stop\n");

	if (!wil_has_other_up_ifaces(wil, ndev)) {
	if (!wil_has_other_active_ifaces(wil, ndev, true, false)) {
		wil_dbg_misc(wil, "stop, last iface\n");
		rc = wil_down(wil);
		if (!rc)
@@ -375,7 +377,7 @@ int wil_vif_add(struct wil6210_priv *wil, struct wil6210_vif *vif)
{
	struct net_device *ndev = vif_to_ndev(vif);
	struct wireless_dev *wdev = vif_to_wdev(vif);
	bool any_active = wil_has_up_ifaces(wil);
	bool any_active = wil_has_active_ifaces(wil, true, false);
	int rc;

	ASSERT_RTNL();
@@ -444,7 +446,7 @@ void wil_vif_remove(struct wil6210_priv *wil, u8 mid)
{
	struct wil6210_vif *vif;
	struct net_device *ndev;
	bool any_active = wil_has_up_ifaces(wil);
	bool any_active = wil_has_active_ifaces(wil, true, false);

	ASSERT_RTNL();
	if (mid >= wil->max_vifs) {
+1 −1
Original line number Diff line number Diff line
@@ -149,7 +149,7 @@ static void wil_remove_all_additional_vifs(struct wil6210_priv *wil)
	for (i = 1; i < wil->max_vifs; i++) {
		vif = wil->vifs[i];
		if (vif) {
			wil_vif_prepare_stop(wil, vif);
			wil_vif_prepare_stop(vif);
			wil_vif_remove(wil, vif->mid);
		}
	}
+5 −4
Original line number Diff line number Diff line
@@ -959,9 +959,9 @@ wil_vif_alloc(struct wil6210_priv *wil, const char *name,
	      unsigned char name_assign_type, enum nl80211_iftype iftype);
void wil_vif_free(struct wil6210_vif *vif);
void *wil_if_alloc(struct device *dev);
bool wil_has_other_up_ifaces(struct wil6210_priv *wil,
			     struct net_device *ndev);
bool wil_has_up_ifaces(struct wil6210_priv *wil);
bool wil_has_other_active_ifaces(struct wil6210_priv *wil,
				 struct net_device *ndev, bool up, bool ok);
bool wil_has_active_ifaces(struct wil6210_priv *wil, bool up, bool ok);
void wil_if_free(struct wil6210_priv *wil);
int wil_vif_add(struct wil6210_priv *wil, struct wil6210_vif *vif);
int wil_if_add(struct wil6210_priv *wil);
@@ -1070,7 +1070,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
int wil_cfg80211_iface_combinations_from_fw(
	struct wil6210_priv *wil,
	const struct wil_fw_record_concurrency *conc);
int wil_vif_prepare_stop(struct wil6210_priv *wil, struct wil6210_vif *vif);
int wil_vif_prepare_stop(struct wil6210_vif *vif);

#if defined(CONFIG_WIL6210_DEBUGFS)
int wil6210_debugfs_init(struct wil6210_priv *wil);
@@ -1116,6 +1116,7 @@ int wil_tx_init(struct wil6210_vif *vif, int cid);
int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size);
int wil_bcast_init(struct wil6210_vif *vif);
void wil_bcast_fini(struct wil6210_vif *vif);
void wil_bcast_fini_all(struct wil6210_priv *wil);

void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring,
			   bool should_stop);
Loading