Commit 5b55b6da authored by Quan Zhou's avatar Quan Zhou Committed by Felix Fietkau
Browse files

wifi: mt76: mt7921: add unified ROC cmd/event support



Add unified ROC cmd/event which is only supported by the newer fw.

Co-developed-by: default avatarSean Wang <sean.wang@mediatek.com>
Signed-off-by: default avatarSean Wang <sean.wang@mediatek.com>
Co-developed-by: default avatarDeren Wu <deren.wu@mediatek.com>
Signed-off-by: default avatarDeren Wu <deren.wu@mediatek.com>
Co-developed-by: default avatarKaikai Hu <kaikai.hu@mediatek.com>
Signed-off-by: default avatarKaikai Hu <kaikai.hu@mediatek.com>
Signed-off-by: default avatarQuan Zhou <quan.zhou@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent a0ab9c31
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -121,11 +121,13 @@ struct mt76_connac2_mcu_rxd {

	u8 eid;
	u8 seq;
	u8 rsv[2];

	u8 option;
	u8 rsv;
	u8 ext_eid;
	u8 rsv1[2];
	u8 s2d_index;

	u8 tlv[0];
};

struct mt76_connac2_patch_hdr {
@@ -957,6 +959,9 @@ enum {
	DEV_INFO_MAX_NUM
};

#define MCU_UNI_CMD_EVENT                       BIT(1)
#define MCU_UNI_CMD_UNSOLICITED_EVENT           BIT(2)

/* event table */
enum {
	MCU_EVENT_TARGET_ADDRESS_LEN = 0x01,
@@ -1163,6 +1168,7 @@ enum {
	MCU_UNI_CMD_OFFLOAD = 0x06,
	MCU_UNI_CMD_HIF_CTRL = 0x07,
	MCU_UNI_CMD_SNIFFER = 0x24,
	MCU_UNI_CMD_ROC = 0x27,
};

enum {
+119 −0
Original line number Diff line number Diff line
@@ -302,6 +302,23 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
	dev_kfree_skb(skb);
}

static void
mt7921_mcu_uni_rx_unsolicited_event(struct mt7921_dev *dev,
				    struct sk_buff *skb)
{
	struct mt76_connac2_mcu_rxd *rxd;

	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;

	switch (rxd->eid) {
	case MCU_UNI_EVENT_ROC:
		break;
	default:
		break;
	}
	dev_kfree_skb(skb);
}

void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb)
{
	struct mt76_connac2_mcu_rxd *rxd;
@@ -311,6 +328,11 @@ void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb)

	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;

	if (rxd->option & MCU_UNI_CMD_UNSOLICITED_EVENT) {
		mt7921_mcu_uni_rx_unsolicited_event(dev, skb);
		return;
	}

	if (rxd->eid == 0x6) {
		mt76_mcu_rx_event(&dev->mt76, skb);
		return;
@@ -636,6 +658,103 @@ int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif)
				 &req_mu, sizeof(req_mu), false);
}

int mt7921_mcu_set_roc(struct mt7921_phy *phy, struct mt7921_vif *vif,
		       struct ieee80211_channel *chan, int duration,
		       enum mt7921_roc_req type, u8 token_id)
{
	int center_ch = ieee80211_frequency_to_channel(chan->center_freq);
	struct mt7921_dev *dev = phy->dev;
	struct {
		struct {
			u8 rsv[4];
		} __packed hdr;
		struct roc_acquire_tlv {
			__le16 tag;
			__le16 len;
			u8 bss_idx;
			u8 tokenid;
			u8 control_channel;
			u8 sco;
			u8 band;
			u8 bw;
			u8 center_chan;
			u8 center_chan2;
			u8 bw_from_ap;
			u8 center_chan_from_ap;
			u8 center_chan2_from_ap;
			u8 reqtype;
			__le32 maxinterval;
			u8 dbdcband;
			u8 rsv[3];
		} __packed roc;
	} __packed req = {
		.roc = {
			.tag = cpu_to_le16(UNI_ROC_ACQUIRE),
			.len = cpu_to_le16(sizeof(struct roc_acquire_tlv)),
			.tokenid = token_id,
			.reqtype = type,
			.maxinterval = cpu_to_le32(duration),
			.bss_idx = vif->mt76.idx,
			.control_channel = chan->hw_value,
			.bw = CMD_CBW_20MHZ,
			.bw_from_ap = CMD_CBW_20MHZ,
			.center_chan = center_ch,
			.center_chan_from_ap = center_ch,
			.dbdcband = 0xff, /* auto */
		},
	};

	if (chan->hw_value < center_ch)
		req.roc.sco = 1; /* SCA */
	else if (chan->hw_value > center_ch)
		req.roc.sco = 3; /* SCB */

	switch (chan->band) {
	case NL80211_BAND_6GHZ:
		req.roc.band = 3;
		break;
	case NL80211_BAND_5GHZ:
		req.roc.band = 2;
		break;
	default:
		req.roc.band = 1;
		break;
	}

	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(ROC),
				 &req, sizeof(req), false);
}

int mt7921_mcu_abort_roc(struct mt7921_phy *phy, struct mt7921_vif *vif,
			 u8 token_id)
{
	struct mt7921_dev *dev = phy->dev;
	struct {
		struct {
			u8 rsv[4];
		} __packed hdr;
		struct roc_abort_tlv {
			__le16 tag;
			__le16 len;
			u8 bss_idx;
			u8 tokenid;
			u8 dbdcband;
			u8 rsv[5];
		} __packed abort;
	} __packed req = {
		.abort = {
			.tag = cpu_to_le16(UNI_ROC_ABORT),
			.len = cpu_to_le16(sizeof(struct roc_abort_tlv)),
			.tokenid = token_id,
			.bss_idx = vif->mt76.idx,
			.dbdcband = 0xff, /* auto*/
		},
	};

	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(ROC),
				 &req, sizeof(req), false);
}

int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd)
{
	struct mt7921_dev *dev = phy->dev;
+19 −0
Original line number Diff line number Diff line
@@ -53,6 +53,20 @@
#define MT7921_SDIO_HDR_TX_BYTES	GENMASK(15, 0)
#define MT7921_SDIO_HDR_PKT_TYPE	GENMASK(17, 16)

#define MCU_UNI_EVENT_ROC  0x27

enum {
	UNI_ROC_ACQUIRE,
	UNI_ROC_ABORT,
	UNI_ROC_NUM
};

enum mt7921_roc_req {
	MT7921_ROC_REQ_JOIN,
	MT7921_ROC_REQ_ROC,
	MT7921_ROC_REQ_NUM
};

enum mt7921_sdio_pkt_type {
	MT7921_SDIO_TXD,
	MT7921_SDIO_DATA,
@@ -508,4 +522,9 @@ int mt7921_set_tx_sar_pwr(struct ieee80211_hw *hw,

int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
		       enum environment_cap env_cap);
int mt7921_mcu_set_roc(struct mt7921_phy *phy, struct mt7921_vif *vif,
		       struct ieee80211_channel *chan, int duration,
		       enum mt7921_roc_req type, u8 token_id);
int mt7921_mcu_abort_roc(struct mt7921_phy *phy, struct mt7921_vif *vif,
			 u8 token_id);
#endif