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

Commit 9e5478b6 authored by Igor Mitsyanko's avatar Igor Mitsyanko Committed by Kalle Valo
Browse files

qtnfmac: retrieve current channel info from EP



Do not try to cache current operational channel info in driver, this
is a potential source of synchronization issues + driver does not
really need that info.

Introduce GET_CHANNEL command and process it appropriately.

Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent fac7f9bf
Loading
Loading
Loading
Loading
+14 −21
Original line number Diff line number Diff line
@@ -793,37 +793,30 @@ qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
	struct qtnf_wmac *mac = wiphy_priv(wiphy);
	struct net_device *ndev = wdev->netdev;
	struct qtnf_vif *vif;
	int ret;

	if (!ndev)
		return -ENODEV;

	vif = qtnf_netdev_get_priv(wdev->netdev);

	switch (vif->wdev.iftype) {
	case NL80211_IFTYPE_STATION:
		if (vif->sta_state == QTNF_STA_DISCONNECTED) {
			pr_warn("%s: STA disconnected\n", ndev->name);
			return -ENODATA;
		}
		break;
	case NL80211_IFTYPE_AP:
		if (!(vif->bss_status & QTNF_STATE_AP_START)) {
			pr_warn("%s: AP not started\n", ndev->name);
			return -ENODATA;
		}
		break;
	default:
		pr_err("unsupported vif type (%d)\n", vif->wdev.iftype);
		return -ENODATA;
	ret = qtnf_cmd_get_channel(vif, chandef);
	if (ret) {
		pr_err("%s: failed to get channel: %d\n", ndev->name, ret);
		goto out;
	}

	if (!cfg80211_chandef_valid(&mac->chandef)) {
		pr_err("invalid channel settings on %s\n", ndev->name);
		return -ENODATA;
	if (!cfg80211_chandef_valid(chandef)) {
		pr_err("%s: bad chan freq1=%u freq2=%u bw=%u\n", ndev->name,
		       chandef->center_freq1, chandef->center_freq2,
		       chandef->width);
		ret = -ENODATA;
	}

	memcpy(chandef, &mac->chandef, sizeof(*chandef));
	return 0;
	memcpy(&mac->chandef, chandef, sizeof(mac->chandef));

out:
	return ret;
}

static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+38 −0
Original line number Diff line number Diff line
@@ -2358,3 +2358,41 @@ int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac,
	qtnf_bus_unlock(mac->bus);
	return ret;
}

int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef)
{
	struct qtnf_bus *bus = vif->mac->bus;
	const struct qlink_resp_channel_get *resp;
	struct sk_buff *cmd_skb;
	struct sk_buff *resp_skb = NULL;
	u16 res_code = QLINK_CMD_RESULT_OK;
	int ret;

	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
					    QLINK_CMD_CHAN_GET,
					    sizeof(struct qlink_cmd));
	if (unlikely(!cmd_skb))
		return -ENOMEM;

	qtnf_bus_lock(bus);

	ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code,
				       sizeof(*resp), NULL);

	qtnf_bus_unlock(bus);

	if (unlikely(ret))
		goto out;

	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
		ret = -ENODATA;
		goto out;
	}

	resp = (const struct qlink_resp_channel_get *)resp_skb->data;
	qlink_chandef_q2cfg(priv_to_wiphy(vif->mac), &resp->chan, chdef);

out:
	consume_skb(resp_skb);
	return ret;
}
+1 −0
Original line number Diff line number Diff line
@@ -75,5 +75,6 @@ int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u16 channel,
			    struct qtnf_chan_stats *stats);
int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac,
			      struct cfg80211_csa_settings *params);
int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef);

#endif /* QLINK_COMMANDS_H_ */
+11 −0
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ enum qlink_cmd_type {
	QLINK_CMD_REG_NOTIFY		= 0x0019,
	QLINK_CMD_CHANS_INFO_GET	= 0x001A,
	QLINK_CMD_CHAN_SWITCH		= 0x001B,
	QLINK_CMD_CHAN_GET		= 0x001C,
	QLINK_CMD_CONFIG_AP		= 0x0020,
	QLINK_CMD_START_AP		= 0x0021,
	QLINK_CMD_STOP_AP		= 0x0022,
@@ -694,6 +695,16 @@ struct qlink_resp_get_chan_stats {
	u8 info[0];
} __packed;

/**
 * struct qlink_resp_channel_get - response for QLINK_CMD_CHAN_GET command
 *
 * @chan: definition of current operating channel.
 */
struct qlink_resp_channel_get {
	struct qlink_resp rhdr;
	struct qlink_chandef chan;
} __packed;

/* QLINK Events messages related definitions
 */