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

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

qtnfmac: make "Channel change" event report full channel info



Specifically, it has to report center frequency, secondary center
frequency (for 80+80) and BW.
Introduce channel definition structure to qlink and modify channel
change event processing function accordingly.

Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 77d68147
Loading
Loading
Loading
Loading
+13 −16
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include "trans.h"
#include "util.h"
#include "event.h"
#include "qlink_util.h"

static int
qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
@@ -359,39 +360,35 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
{
	struct wiphy *wiphy = priv_to_wiphy(mac);
	struct cfg80211_chan_def chandef;
	struct ieee80211_channel *chan;
	struct qtnf_vif *vif;
	int freq;
	int i;

	if (len < sizeof(*data)) {
		pr_err("payload is too short\n");
		pr_err("MAC%u: payload is too short\n", mac->macid);
		return -EINVAL;
	}

	freq = le32_to_cpu(data->freq);
	chan = ieee80211_get_channel(wiphy, freq);
	if (!chan) {
		pr_err("channel at %d MHz not found\n", freq);
	qlink_chandef_q2cfg(wiphy, &data->chan, &chandef);

	if (!cfg80211_chandef_valid(&chandef)) {
		pr_err("MAC%u: bad channel f1=%u f2=%u bw=%u\n", mac->macid,
		       chandef.center_freq1, chandef.center_freq2,
		       chandef.width);
		return -EINVAL;
	}

	pr_debug("MAC%d switch to new channel %u MHz\n", mac->macid, freq);
	pr_debug("MAC%d: new channel ieee=%u freq1=%u freq2=%u bw=%u\n",
		 mac->macid, chandef.chan->hw_value, chandef.center_freq1,
		 chandef.center_freq2, chandef.width);

	if (mac->status & QTNF_MAC_CSA_ACTIVE) {
		mac->status &= ~QTNF_MAC_CSA_ACTIVE;
		if (chan->hw_value != mac->csa_chandef.chan->hw_value)
		if (chandef.chan->hw_value != mac->csa_chandef.chan->hw_value)
			pr_warn("unexpected switch to %u during CSA to %u\n",
				chan->hw_value,
				chandef.chan->hw_value,
				mac->csa_chandef.chan->hw_value);
	}

	/* FIXME: need to figure out proper nl80211_channel_type value */
	cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
	/* fall-back to minimal safe chandef description */
	if (!cfg80211_chandef_valid(&chandef))
		cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);

	memcpy(&mac->chandef, &chandef, sizeof(mac->chandef));

	for (i = 0; i < QTNF_MAX_INTF; i++) {
+16 −2
Original line number Diff line number Diff line
@@ -118,6 +118,20 @@ enum qlink_channel_width {
	QLINK_CHAN_WIDTH_160,
};

/**
 * struct qlink_chandef - qlink channel definition
 *
 * @center_freq1: center frequency of first segment
 * @center_freq2: center frequency of second segment (80+80 only)
 * @width: channel width, one of @enum qlink_channel_width
 */
struct qlink_chandef {
	__le16 center_freq1;
	__le16 center_freq2;
	u8 width;
	u8 rsvd[3];
} __packed;

/* QLINK Command messages related definitions
 */

@@ -764,11 +778,11 @@ struct qlink_event_bss_leave {
/**
 * struct qlink_event_freq_change - data for QLINK_EVENT_FREQ_CHANGE event
 *
 * @freq: new operating frequency in MHz
 * @chan: new operating channel definition
 */
struct qlink_event_freq_change {
	struct qlink_event ehdr;
	__le32 freq;
	struct qlink_chandef chan;
} __packed;

enum qlink_rxmgmt_flags {
+52 −0
Original line number Diff line number Diff line
@@ -75,3 +75,55 @@ u8 qlink_chan_width_mask_to_nl(u16 qlink_mask)

	return result;
}

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

void qlink_chandef_q2cfg(struct wiphy *wiphy,
			 const struct qlink_chandef *qch,
			 struct cfg80211_chan_def *chdef)
{
	chdef->center_freq1 = le16_to_cpu(qch->center_freq1);
	chdef->center_freq2 = le16_to_cpu(qch->center_freq2);
	chdef->width = qlink_chanwidth_to_nl(qch->width);

	switch (chdef->width) {
	case NL80211_CHAN_WIDTH_20_NOHT:
	case NL80211_CHAN_WIDTH_20:
	case NL80211_CHAN_WIDTH_5:
	case NL80211_CHAN_WIDTH_10:
		chdef->chan = ieee80211_get_channel(wiphy, chdef->center_freq1);
		break;
	case NL80211_CHAN_WIDTH_40:
	case NL80211_CHAN_WIDTH_80:
	case NL80211_CHAN_WIDTH_80P80:
	case NL80211_CHAN_WIDTH_160:
		chdef->chan = ieee80211_get_channel(wiphy,
						    chdef->center_freq1 - 10);
		break;
	default:
		chdef->chan = NULL;
		break;
	}
}
+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <linux/types.h>
#include <linux/skbuff.h>
#include <net/cfg80211.h>

#include "qlink.h"

@@ -62,5 +63,8 @@ static inline void qtnf_cmd_skb_put_tlv_u16(struct sk_buff *skb,

u16 qlink_iface_type_to_nl_mask(u16 qlink_type);
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);

#endif /* _QTN_FMAC_QLINK_UTIL_H_ */