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

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

qtnfmac: pass channel definition to WiFi card on START_AP command



Introduce "channel definition" TLV containing full channel
description (center frequence for both segments + BW) and pass it to
wireless card in a payload to START_AP command.

Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 8b5f4aa7
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -266,17 +266,8 @@ static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev,
			 struct cfg80211_ap_settings *settings)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	struct qtnf_wmac *mac = wiphy_priv(wiphy);
	int ret;

	if (!cfg80211_chandef_identical(&mac->chandef, &settings->chandef)) {
		memcpy(&mac->chandef, &settings->chandef, sizeof(mac->chandef));
		if (vif->vifid != 0)
			pr_warn("%s: unexpected chan %u (%u MHz)\n", dev->name,
				settings->chandef.chan->hw_value,
				settings->chandef.chan->center_freq);
	}

	ret = qtnf_cmd_send_config_ap(vif, settings);
	if (ret) {
		pr_err("VIF%u.%u: failed to push config to FW\n",
+15 −13
Original line number Diff line number Diff line
@@ -185,8 +185,6 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif,
			    const struct cfg80211_ap_settings *s)
{
	struct sk_buff *cmd_skb;
	struct cfg80211_chan_def *chandef = &vif->mac->chandef;
	struct qlink_tlv_channel *qchan;
	struct qlink_cmd_config_ap *cmd;
	struct qlink_auth_encr *aen;
	u16 res_code = QLINK_CMD_RESULT_OK;
@@ -211,17 +209,6 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif,
	cmd->ht_required = s->ht_required;
	cmd->vht_required = s->vht_required;

	if (s->ssid && s->ssid_len > 0 && s->ssid_len <= IEEE80211_MAX_SSID_LEN)
		qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, s->ssid,
					 s->ssid_len);

	qchan = skb_put_zero(cmd_skb, sizeof(*qchan));
	qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
	qchan->hdr.len = cpu_to_le16(sizeof(*qchan) -
			sizeof(struct qlink_tlv_hdr));
	qchan->hw_value = cpu_to_le16(
		ieee80211_frequency_to_channel(chandef->chan->center_freq));

	aen = &cmd->aen;
	aen->auth_type = s->auth_type;
	aen->privacy = !!s->privacy;
@@ -240,6 +227,21 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif,
	aen->control_port_ethertype =
		cpu_to_le16(be16_to_cpu(s->crypto.control_port_ethertype));

	if (s->ssid && s->ssid_len > 0 && s->ssid_len <= IEEE80211_MAX_SSID_LEN)
		qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, s->ssid,
					 s->ssid_len);

	if (cfg80211_chandef_valid(&s->chandef)) {
		struct qlink_tlv_chandef *chtlv =
			(struct qlink_tlv_chandef *)skb_put(cmd_skb,
							    sizeof(*chtlv));

		chtlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANDEF);
		chtlv->hdr.len = cpu_to_le16(sizeof(*chtlv) -
					     sizeof(chtlv->hdr));
		qlink_chandef_cfg2q(&s->chandef, &chtlv->chan);
	}

	qtnf_bus_lock(vif->mac->bus);

	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
+13 −0
Original line number Diff line number Diff line
@@ -941,6 +941,7 @@ enum qlink_tlv_id {
	QTN_TLV_ID_LRETRY_LIMIT		= 0x0204,
	QTN_TLV_ID_REG_RULE		= 0x0207,
	QTN_TLV_ID_CHANNEL		= 0x020F,
	QTN_TLV_ID_CHANDEF		= 0x0210,
	QTN_TLV_ID_COVERAGE_CLASS	= 0x0213,
	QTN_TLV_ID_IFACE_LIMIT		= 0x0214,
	QTN_TLV_ID_NUM_IFACE_COMB	= 0x0215,
@@ -1128,6 +1129,18 @@ struct qlink_tlv_channel {
	u8 rsvd[2];
} __packed;

/**
 * struct qlink_tlv_chandef - data for QTN_TLV_ID_CHANDEF TLV
 *
 * Channel definition.
 *
 * @chan: channel definition data.
 */
struct qlink_tlv_chandef {
	struct qlink_tlv_hdr hdr;
	struct qlink_chandef chan;
} __packed;

struct qlink_chan_stats {
	__le32 chan_num;
	__le32 cca_tx;
+32 −0
Original line number Diff line number Diff line
@@ -128,6 +128,38 @@ void qlink_chandef_q2cfg(struct wiphy *wiphy,
	}
}

static u8 qlink_chanwidth_nl_to_qlink(enum nl80211_chan_width nlwidth)
{
	switch (nlwidth) {
	case NL80211_CHAN_WIDTH_20_NOHT:
		return QLINK_CHAN_WIDTH_20_NOHT;
	case NL80211_CHAN_WIDTH_20:
		return QLINK_CHAN_WIDTH_20;
	case NL80211_CHAN_WIDTH_40:
		return QLINK_CHAN_WIDTH_40;
	case NL80211_CHAN_WIDTH_80:
		return QLINK_CHAN_WIDTH_80;
	case NL80211_CHAN_WIDTH_80P80:
		return QLINK_CHAN_WIDTH_80P80;
	case NL80211_CHAN_WIDTH_160:
		return QLINK_CHAN_WIDTH_160;
	case NL80211_CHAN_WIDTH_5:
		return QLINK_CHAN_WIDTH_5;
	case NL80211_CHAN_WIDTH_10:
		return QLINK_CHAN_WIDTH_10;
	default:
		return -1;
	}
}

void qlink_chandef_cfg2q(const struct cfg80211_chan_def *chdef,
			 struct qlink_chandef *qch)
{
	qch->center_freq1 = cpu_to_le16(chdef->center_freq1);
	qch->center_freq2 = cpu_to_le16(chdef->center_freq2);
	qch->width = qlink_chanwidth_nl_to_qlink(chdef->width);
}

enum qlink_hidden_ssid qlink_hidden_ssid_nl2q(enum nl80211_hidden_ssid nl_val)
{
	switch (nl_val) {
+2 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ u8 qlink_chan_width_mask_to_nl(u16 qlink_mask);
void qlink_chandef_q2cfg(struct wiphy *wiphy,
			 const struct qlink_chandef *qch,
			 struct cfg80211_chan_def *chdef);
void qlink_chandef_cfg2q(const struct cfg80211_chan_def *chdef,
			 struct qlink_chandef *qch);
enum qlink_hidden_ssid qlink_hidden_ssid_nl2q(enum nl80211_hidden_ssid nl_val);

#endif /* _QTN_FMAC_QLINK_UTIL_H_ */