mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
mt76: mt76_connac: move hw_scan and sched_scan routine in mt76_connac_mcu module
Move hw_scan/sched_scan in mt76_connac_mcu module in order to be reused in mt7615 and mt7921 drivers Signed-off-by: Lorenzo Bianconi <[email protected]> Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
committed by
Felix Fietkau
parent
50349a8664
commit
c88859180c
@@ -982,5 +982,202 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
|
||||
|
||||
#define MT76_CONNAC_SCAN_CHANNEL_TIME 60
|
||||
int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *scan_req)
|
||||
{
|
||||
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
|
||||
struct cfg80211_scan_request *sreq = &scan_req->req;
|
||||
int n_ssids = 0, err, i, duration = MT76_CONNAC_SCAN_CHANNEL_TIME;
|
||||
int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
|
||||
struct ieee80211_channel **scan_list = sreq->channels;
|
||||
struct mt76_dev *mdev = phy->dev;
|
||||
bool ext_phy = phy == mdev->phy2;
|
||||
struct mt76_connac_mcu_scan_channel *chan;
|
||||
struct mt76_connac_hw_scan_req *req;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
set_bit(MT76_HW_SCANNING, &phy->state);
|
||||
mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
|
||||
|
||||
req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req));
|
||||
|
||||
req->seq_num = mvif->scan_seq_num | ext_phy << 7;
|
||||
req->bss_idx = mvif->idx;
|
||||
req->scan_type = sreq->n_ssids ? 1 : 0;
|
||||
req->probe_req_num = sreq->n_ssids ? 2 : 0;
|
||||
req->version = 1;
|
||||
|
||||
for (i = 0; i < sreq->n_ssids; i++) {
|
||||
if (!sreq->ssids[i].ssid_len)
|
||||
continue;
|
||||
|
||||
req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
|
||||
memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid,
|
||||
sreq->ssids[i].ssid_len);
|
||||
n_ssids++;
|
||||
}
|
||||
req->ssid_type = n_ssids ? BIT(2) : BIT(0);
|
||||
req->ssid_type_ext = n_ssids ? BIT(0) : 0;
|
||||
req->ssids_num = n_ssids;
|
||||
|
||||
/* increase channel time for passive scan */
|
||||
if (!sreq->n_ssids)
|
||||
duration *= 2;
|
||||
req->timeout_value = cpu_to_le16(sreq->n_channels * duration);
|
||||
req->channel_min_dwell_time = cpu_to_le16(duration);
|
||||
req->channel_dwell_time = cpu_to_le16(duration);
|
||||
|
||||
req->channels_num = min_t(u8, sreq->n_channels, 32);
|
||||
req->ext_channels_num = min_t(u8, ext_channels_num, 32);
|
||||
for (i = 0; i < req->channels_num + req->ext_channels_num; i++) {
|
||||
if (i >= 32)
|
||||
chan = &req->ext_channels[i - 32];
|
||||
else
|
||||
chan = &req->channels[i];
|
||||
|
||||
chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
|
||||
chan->channel_num = scan_list[i]->hw_value;
|
||||
}
|
||||
req->channel_type = sreq->n_channels ? 4 : 0;
|
||||
|
||||
if (sreq->ie_len > 0) {
|
||||
memcpy(req->ies, sreq->ie, sreq->ie_len);
|
||||
req->ies_len = cpu_to_le16(sreq->ie_len);
|
||||
}
|
||||
|
||||
memcpy(req->bssid, sreq->bssid, ETH_ALEN);
|
||||
if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
|
||||
get_random_mask_addr(req->random_mac, sreq->mac_addr,
|
||||
sreq->mac_addr_mask);
|
||||
req->scan_func = 1;
|
||||
}
|
||||
|
||||
err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_START_HW_SCAN, false);
|
||||
if (err < 0)
|
||||
clear_bit(MT76_HW_SCANNING, &phy->state);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan);
|
||||
|
||||
int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
|
||||
struct {
|
||||
u8 seq_num;
|
||||
u8 is_ext_channel;
|
||||
u8 rsv[2];
|
||||
} __packed req = {
|
||||
.seq_num = mvif->scan_seq_num,
|
||||
};
|
||||
|
||||
if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) {
|
||||
struct cfg80211_scan_info info = {
|
||||
.aborted = true,
|
||||
};
|
||||
|
||||
ieee80211_scan_completed(phy->hw, &info);
|
||||
}
|
||||
|
||||
return mt76_mcu_send_msg(phy->dev, MCU_CMD_CANCEL_HW_SCAN, &req,
|
||||
sizeof(req), false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan);
|
||||
|
||||
int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_sched_scan_request *sreq)
|
||||
{
|
||||
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
|
||||
struct ieee80211_channel **scan_list = sreq->channels;
|
||||
struct mt76_connac_mcu_scan_channel *chan;
|
||||
struct mt76_connac_sched_scan_req *req;
|
||||
struct mt76_dev *mdev = phy->dev;
|
||||
bool ext_phy = phy == mdev->phy2;
|
||||
struct cfg80211_match_set *match;
|
||||
struct cfg80211_ssid *ssid;
|
||||
struct sk_buff *skb;
|
||||
int i;
|
||||
|
||||
skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
|
||||
|
||||
req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req));
|
||||
req->version = 1;
|
||||
req->seq_num = mvif->scan_seq_num | ext_phy << 7;
|
||||
|
||||
if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
|
||||
get_random_mask_addr(req->random_mac, sreq->mac_addr,
|
||||
sreq->mac_addr_mask);
|
||||
req->scan_func = 1;
|
||||
}
|
||||
|
||||
req->ssids_num = sreq->n_ssids;
|
||||
for (i = 0; i < req->ssids_num; i++) {
|
||||
ssid = &sreq->ssids[i];
|
||||
memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
|
||||
req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
|
||||
}
|
||||
|
||||
req->match_num = sreq->n_match_sets;
|
||||
for (i = 0; i < req->match_num; i++) {
|
||||
match = &sreq->match_sets[i];
|
||||
memcpy(req->match[i].ssid, match->ssid.ssid,
|
||||
match->ssid.ssid_len);
|
||||
req->match[i].rssi_th = cpu_to_le32(match->rssi_thold);
|
||||
req->match[i].ssid_len = match->ssid.ssid_len;
|
||||
}
|
||||
|
||||
req->channel_type = sreq->n_channels ? 4 : 0;
|
||||
req->channels_num = min_t(u8, sreq->n_channels, 64);
|
||||
for (i = 0; i < req->channels_num; i++) {
|
||||
chan = &req->channels[i];
|
||||
chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
|
||||
chan->channel_num = scan_list[i]->hw_value;
|
||||
}
|
||||
|
||||
req->intervals_num = sreq->n_scan_plans;
|
||||
for (i = 0; i < req->intervals_num; i++)
|
||||
req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval);
|
||||
|
||||
if (sreq->ie_len > 0) {
|
||||
req->ie_len = cpu_to_le16(sreq->ie_len);
|
||||
memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len);
|
||||
}
|
||||
|
||||
return mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_SCHED_SCAN_REQ, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req);
|
||||
|
||||
int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
bool enable)
|
||||
{
|
||||
struct {
|
||||
u8 active; /* 0: enabled 1: disabled */
|
||||
u8 rsv[3];
|
||||
} __packed req = {
|
||||
.active = !enable,
|
||||
};
|
||||
|
||||
if (enable)
|
||||
set_bit(MT76_HW_SCHED_SCANNING, &phy->state);
|
||||
else
|
||||
clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
|
||||
|
||||
return mt76_mcu_send_msg(phy->dev, MCU_CMD_SCHED_SCAN_ENABLE, &req,
|
||||
sizeof(req), false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
|
||||
|
||||
MODULE_AUTHOR("Lorenzo Bianconi <[email protected]>");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
Reference in New Issue
Block a user