Commit 5ec87dc8 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

mt76: mt7615: add csa support

Add Channel Switch Announcement support to mt7615 driver updating beacon
template with CSA IE received from mac80211
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 02fc62e3
...@@ -257,6 +257,7 @@ int mt7615_register_device(struct mt7615_dev *dev) ...@@ -257,6 +257,7 @@ int mt7615_register_device(struct mt7615_dev *dev)
wiphy->iface_combinations = if_comb; wiphy->iface_combinations = if_comb;
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
wiphy->reg_notifier = mt7615_regd_notifier; wiphy->reg_notifier = mt7615_regd_notifier;
wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN); ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
......
...@@ -305,6 +305,18 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw, ...@@ -305,6 +305,18 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
} }
static void
mt7615_channel_switch_beacon(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_chan_def *chandef)
{
struct mt7615_dev *dev = hw->priv;
mutex_lock(&dev->mt76.mutex);
mt7615_mcu_set_bcn(dev, vif, true);
mutex_unlock(&dev->mt76.mutex);
}
int mt7615_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, int mt7615_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta) struct ieee80211_sta *sta)
{ {
...@@ -496,4 +508,5 @@ const struct ieee80211_ops mt7615_ops = { ...@@ -496,4 +508,5 @@ const struct ieee80211_ops mt7615_ops = {
.sw_scan_complete = mt7615_sw_scan_complete, .sw_scan_complete = mt7615_sw_scan_complete,
.release_buffered_frames = mt76_release_buffered_frames, .release_buffered_frames = mt76_release_buffered_frames,
.get_txpower = mt76_get_txpower, .get_txpower = mt76_get_txpower,
.channel_switch_beacon = mt7615_channel_switch_beacon,
}; };
...@@ -159,6 +159,13 @@ mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data, ...@@ -159,6 +159,13 @@ mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
return ret; return ret;
} }
static void
mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
if (vif->csa_active)
ieee80211_csa_finish(vif);
}
static void static void
mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb) mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb)
{ {
...@@ -169,6 +176,11 @@ mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb) ...@@ -169,6 +176,11 @@ mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb)
ieee80211_radar_detected(dev->mt76.hw); ieee80211_radar_detected(dev->mt76.hw);
dev->hw_pattern++; dev->hw_pattern++;
break; break;
case MCU_EXT_EVENT_CSA_NOTIFY:
ieee80211_iterate_active_interfaces_atomic(dev->mt76.hw,
IEEE80211_IFACE_ITER_RESUME_ALL,
mt7615_mcu_csa_finish, dev);
break;
default: default:
break; break;
} }
...@@ -1143,6 +1155,7 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif, ...@@ -1143,6 +1155,7 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif,
{ {
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
struct mt76_wcid *wcid = &dev->mt76.global_wcid; struct mt76_wcid *wcid = &dev->mt76.global_wcid;
struct ieee80211_mutable_offsets offs;
struct req { struct req {
u8 omac_idx; u8 omac_idx;
u8 enable; u8 enable;
...@@ -1163,13 +1176,10 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif, ...@@ -1163,13 +1176,10 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif,
.enable = en, .enable = en,
.wlan_idx = wcid->idx, .wlan_idx = wcid->idx,
.band_idx = mvif->band_idx, .band_idx = mvif->band_idx,
/* pky_type: 0 for bcn, 1 for tim */
.pkt_type = 0,
}; };
struct sk_buff *skb; struct sk_buff *skb;
u16 tim_off;
skb = ieee80211_beacon_get_tim(mt76_hw(dev), vif, &tim_off, NULL); skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs);
if (!skb) if (!skb)
return -EINVAL; return -EINVAL;
...@@ -1183,8 +1193,14 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif, ...@@ -1183,8 +1193,14 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif,
0, NULL); 0, NULL);
memcpy(req.pkt + MT_TXD_SIZE, skb->data, skb->len); memcpy(req.pkt + MT_TXD_SIZE, skb->data, skb->len);
req.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len); req.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
req.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + tim_off); req.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
if (offs.csa_counter_offs[0]) {
u16 csa_offs;
csa_offs = MT_TXD_SIZE + offs.csa_counter_offs[0] - 4;
req.csa_ie_pos = cpu_to_le16(csa_offs);
req.csa_cnt = skb->data[offs.csa_counter_offs[0]];
}
dev_kfree_skb(skb); dev_kfree_skb(skb);
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_BCN_OFFLOAD, return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_BCN_OFFLOAD,
......
...@@ -42,6 +42,7 @@ enum { ...@@ -42,6 +42,7 @@ enum {
MCU_EXT_EVENT_THERMAL_PROTECT = 0x22, MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
MCU_EXT_EVENT_ASSERT_DUMP = 0x23, MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
MCU_EXT_EVENT_RDD_REPORT = 0x3a, MCU_EXT_EVENT_RDD_REPORT = 0x3a,
MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
}; };
struct mt7615_mcu_rxd { struct mt7615_mcu_rxd {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment