diff --git a/mt7615/mac.c b/mt7615/mac.c index 16233ced0..49924d502 100644 --- a/mt7615/mac.c +++ b/mt7615/mac.c @@ -17,6 +17,44 @@ #define to_rssi(field, rxv) ((FIELD_GET(field, rxv) - 220) / 2) +static const struct mt7615_dfs_radar_spec etsi_radar_specs = { + .pulse_th = { 40, -10, -80, 800, 3360, 128, 5200 }, + .radar_pattern = { + [5] = { 1, 0, 6, 32, 28, 0, 17, 990, 5010, 1, 1 }, + [6] = { 1, 0, 9, 32, 28, 0, 27, 615, 5010, 1, 1 }, + [7] = { 1, 0, 15, 32, 28, 0, 27, 240, 445, 1, 1 }, + [8] = { 1, 0, 12, 32, 28, 0, 42, 240, 510, 1, 1 }, + [9] = { 1, 1, 0, 0, 0, 0, 14, 2490, 3343, 0, 0, 12, 32, 28 }, + [10] = { 1, 1, 0, 0, 0, 0, 14, 2490, 3343, 0, 0, 15, 32, 24 }, + [11] = { 1, 1, 0, 0, 0, 0, 14, 823, 2510, 0, 0, 18, 32, 28 }, + [12] = { 1, 1, 0, 0, 0, 0, 14, 823, 2510, 0, 0, 27, 32, 24 }, + }, +}; + +static const struct mt7615_dfs_radar_spec fcc_radar_specs = { + .pulse_th = { 40, -10, -80, 800, 3360, 128, 5200 }, + .radar_pattern = { + [0] = { 1, 0, 9, 32, 28, 0, 13, 508, 3076, 1, 1 }, + [1] = { 1, 0, 12, 32, 28, 0, 17, 140, 240, 1, 1 }, + [2] = { 1, 0, 8, 32, 28, 0, 22, 190, 510, 1, 1 }, + [3] = { 1, 0, 6, 32, 28, 0, 32, 190, 510, 1, 1 }, + [4] = { 1, 0, 9, 255, 28, 0, 13, 323, 343, 1, 32 }, + }, +}; + +static const struct mt7615_dfs_radar_spec jp_radar_specs = { + .pulse_th = { 40, -10, -80, 800, 3360, 128, 5200 }, + .radar_pattern = { + [0] = { 1, 0, 8, 32, 28, 0, 13, 508, 3076, 1, 1 }, + [1] = { 1, 0, 12, 32, 28, 0, 17, 140, 240, 1, 1 }, + [2] = { 1, 0, 8, 32, 28, 0, 22, 190, 510, 1, 1 }, + [3] = { 1, 0, 6, 32, 28, 0, 32, 190, 510, 1, 1 }, + [4] = { 1, 0, 9, 32, 28, 0, 13, 323, 343, 1, 32 }, + [13] = { 1, 0, 8, 32, 28, 0, 14, 3836, 3856, 1, 1 }, + [14] = { 1, 0, 8, 32, 28, 0, 14, 3990, 4010, 1, 1 }, + }, +}; + static struct mt76_wcid *mt7615_rx_get_wcid(struct mt7615_dev *dev, u8 idx, bool unicast) { @@ -1685,6 +1723,40 @@ static int mt7615_dfs_start_radar_detector(struct mt7615_phy *phy) return 0; } +static int +mt7615_dfs_init_radar_specs(struct mt7615_phy *phy) +{ + const struct mt7615_dfs_radar_spec *radar_specs; + struct mt7615_dev *dev = phy->dev; + int err, i; + + switch (dev->mt76.region) { + case NL80211_DFS_FCC: + radar_specs = &fcc_radar_specs; + err = mt7615_mcu_set_fcc5_lpn(dev, 8); + if (err < 0) + return err; + break; + case NL80211_DFS_ETSI: + radar_specs = &etsi_radar_specs; + break; + case NL80211_DFS_JP: + radar_specs = &jp_radar_specs; + break; + default: + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(radar_specs->radar_pattern); i++) { + err = mt7615_mcu_set_radar_th(dev, i, + &radar_specs->radar_pattern[i]); + if (err < 0) + return err; + } + + return mt7615_mcu_set_pulse_th(dev, &radar_specs->pulse_th); +} + int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy) { struct cfg80211_chan_def *chandef = &phy->mt76->chandef; @@ -1706,6 +1778,12 @@ int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy) if (phy->dfs_state == chandef->chan->dfs_state) return 0; + err = mt7615_dfs_init_radar_specs(phy); + if (err < 0) { + phy->dfs_state = -1; + goto stop; + } + phy->dfs_state = chandef->chan->dfs_state; if (chandef->chan->flags & IEEE80211_CHAN_RADAR) { diff --git a/mt7615/mac.h b/mt7615/mac.h index 8579b8297..8f053fadd 100644 --- a/mt7615/mac.h +++ b/mt7615/mac.h @@ -306,6 +306,38 @@ struct mt7615_tx_free { #define MT_TXS6_F1_RCPI_1 GENMASK(15, 8) #define MT_TXS6_F1_RCPI_0 GENMASK(7, 0) +struct mt7615_dfs_pulse { + u32 max_width; /* us */ + int max_pwr; /* dbm */ + int min_pwr; /* dbm */ + u32 min_stgr_pri; /* us */ + u32 max_stgr_pri; /* us */ + u32 min_cr_pri; /* us */ + u32 max_cr_pri; /* us */ +}; + +struct mt7615_dfs_pattern { + u8 enb; + u8 stgr; + u8 min_crpn; + u8 max_crpn; + u8 min_crpr; + u8 min_pw; + u8 max_pw; + u32 min_pri; + u32 max_pri; + u8 min_crbn; + u8 max_crbn; + u8 min_stgpn; + u8 max_stgpn; + u8 min_stgpr; +}; + +struct mt7615_dfs_radar_spec { + struct mt7615_dfs_pulse pulse_th; + struct mt7615_dfs_pattern radar_pattern[16]; +}; + enum mt7615_cipher_type { MT_CIPHER_NONE, MT_CIPHER_WEP40, diff --git a/mt7615/mcu.c b/mt7615/mcu.c index 9eab84d50..4f00cb5eb 100644 --- a/mt7615/mcu.c +++ b/mt7615/mcu.c @@ -1372,6 +1372,54 @@ int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev, &req, sizeof(req), true); } +int mt7615_mcu_set_fcc5_lpn(struct mt7615_dev *dev, int val) +{ + struct { + u16 tag; + u16 min_lpn; + } req = { + .tag = 0x1, + .min_lpn = val, + }; + + return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_TH, + &req, sizeof(req), true); +} + +int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev, + const struct mt7615_dfs_pulse *pulse) +{ + struct { + u16 tag; + struct mt7615_dfs_pulse pulse; + } req = { + .tag = 0x3, + }; + + memcpy(&req.pulse, pulse, sizeof(*pulse)); + + return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_TH, + &req, sizeof(req), true); +} + +int mt7615_mcu_set_radar_th(struct mt7615_dev *dev, int index, + const struct mt7615_dfs_pattern *pattern) +{ + struct { + u16 tag; + u16 radar_type; + struct mt7615_dfs_pattern pattern; + } req = { + .tag = 0x2, + .radar_type = index, + }; + + memcpy(&req.pattern, pattern, sizeof(*pattern)); + + return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_TH, + &req, sizeof(req), true); +} + int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev) { struct { diff --git a/mt7615/mcu.h b/mt7615/mcu.h index fa30c6bbc..d65c41932 100644 --- a/mt7615/mcu.h +++ b/mt7615/mcu.h @@ -153,6 +153,7 @@ enum { MCU_EXT_CMD_MAC_INIT_CTRL = 0x46, MCU_EXT_CMD_BCN_OFFLOAD = 0x49, MCU_EXT_CMD_SET_RX_PATH = 0x4e, + MCU_EXT_CMD_SET_RDD_TH = 0x7c, MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d, }; diff --git a/mt7615/mt7615.h b/mt7615/mt7615.h index 055168a6a..450ce5611 100644 --- a/mt7615/mt7615.h +++ b/mt7615/mt7615.h @@ -46,6 +46,8 @@ struct mt7615_vif; struct mt7615_sta; +struct mt7615_dfs_pulse; +struct mt7615_dfs_pattern; enum mt7615_hw_txq_id { MT7615_TXQ_MAIN, @@ -343,6 +345,11 @@ void mt7615_mac_work(struct work_struct *work); void mt7615_txp_skb_unmap(struct mt76_dev *dev, struct mt76_txwi_cache *txwi); int mt76_dfs_start_rdd(struct mt7615_dev *dev, bool force); +int mt7615_mcu_set_fcc5_lpn(struct mt7615_dev *dev, int val); +int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev, + const struct mt7615_dfs_pulse *pulse); +int mt7615_mcu_set_radar_th(struct mt7615_dev *dev, int index, + const struct mt7615_dfs_pattern *pattern); int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy); int mt7615_init_debugfs(struct mt7615_dev *dev);