Skip to content

Commit

Permalink
mt76: mt76_connac: move hw_scan and sched_scan routine in mt76_connac…
Browse files Browse the repository at this point in the history
…_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 <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
LorenzoBianconi authored and nbd168 committed Jan 29, 2021
1 parent 50349a8 commit c888591
Show file tree
Hide file tree
Showing 7 changed files with 359 additions and 356 deletions.
9 changes: 5 additions & 4 deletions mt7615/init.c
Expand Up @@ -353,11 +353,12 @@ mt7615_init_wiphy(struct ieee80211_hw *hw)
}
wiphy->reg_notifier = mt7615_regd_notifier;

wiphy->max_sched_scan_plan_interval = MT7615_MAX_SCHED_SCAN_INTERVAL;
wiphy->max_sched_scan_plan_interval =
MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL;
wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
wiphy->max_scan_ie_len = MT7615_SCAN_IE_LEN;
wiphy->max_sched_scan_ssids = MT7615_MAX_SCHED_SCAN_SSID;
wiphy->max_match_sets = MT7615_MAX_SCAN_MATCH;
wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
wiphy->max_sched_scan_reqs = 1;
wiphy->max_scan_ssids = 4;

Expand Down
20 changes: 15 additions & 5 deletions mt7615/main.c
Expand Up @@ -997,8 +997,12 @@ mt7615_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct mt76_phy *mphy = hw->priv;
int err;

/* fall-back to sw-scan */
if (!mt7615_firmware_offload(dev))
return 1;

mt7615_mutex_acquire(dev);
err = mt7615_mcu_hw_scan(mphy->priv, vif, req);
err = mt76_connac_mcu_hw_scan(mphy, vif, req);
mt7615_mutex_release(dev);

return err;
Expand All @@ -1011,7 +1015,7 @@ mt7615_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
struct mt76_phy *mphy = hw->priv;

mt7615_mutex_acquire(dev);
mt7615_mcu_cancel_hw_scan(mphy->priv, vif);
mt76_connac_mcu_cancel_hw_scan(mphy, vif);
mt7615_mutex_release(dev);
}

Expand All @@ -1024,13 +1028,16 @@ mt7615_start_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct mt76_phy *mphy = hw->priv;
int err;

if (!mt7615_firmware_offload(dev))
return -EOPNOTSUPP;

mt7615_mutex_acquire(dev);

err = mt7615_mcu_sched_scan_req(mphy->priv, vif, req);
err = mt76_connac_mcu_sched_scan_req(mphy, vif, req);
if (err < 0)
goto out;

err = mt7615_mcu_sched_scan_enable(mphy->priv, vif, true);
err = mt76_connac_mcu_sched_scan_enable(mphy, vif, true);
out:
mt7615_mutex_release(dev);

Expand All @@ -1044,8 +1051,11 @@ mt7615_stop_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
struct mt76_phy *mphy = hw->priv;
int err;

if (!mt7615_firmware_offload(dev))
return -EOPNOTSUPP;

mt7615_mutex_acquire(dev);
err = mt7615_mcu_sched_scan_enable(mphy->priv, vif, false);
err = mt76_connac_mcu_sched_scan_enable(mphy, vif, false);
mt7615_mutex_release(dev);

return err;
Expand Down
213 changes: 3 additions & 210 deletions mt7615/mcu.c
Expand Up @@ -2290,214 +2290,6 @@ int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable)
sizeof(req), true);
}

#define MT7615_SCAN_CHANNEL_TIME 60
int mt7615_mcu_hw_scan(struct mt7615_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_scan_request *scan_req)
{
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
struct cfg80211_scan_request *sreq = &scan_req->req;
int n_ssids = 0, err, i, duration = MT7615_SCAN_CHANNEL_TIME;
int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
struct ieee80211_channel **scan_list = sreq->channels;
struct mt7615_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy;
struct mt7615_mcu_scan_channel *chan;
struct mt7615_hw_scan_req *req;
struct sk_buff *skb;

/* fall-back to sw-scan */
if (!mt7615_firmware_offload(dev))
return 1;

skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(*req));
if (!skb)
return -ENOMEM;

set_bit(MT76_HW_SCANNING, &phy->mt76->state);
mvif->mt76.scan_seq_num = (mvif->mt76.scan_seq_num + 1) & 0x7f;

req = (struct mt7615_hw_scan_req *)skb_put(skb, sizeof(*req));

req->seq_num = mvif->mt76.scan_seq_num | ext_phy << 7;
req->bss_idx = mvif->mt76.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(&dev->mt76, skb, MCU_CMD_START_HW_SCAN,
false);
if (err < 0)
clear_bit(MT76_HW_SCANNING, &phy->mt76->state);

return err;
}

int mt7615_mcu_cancel_hw_scan(struct mt7615_phy *phy,
struct ieee80211_vif *vif)
{
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
struct mt7615_dev *dev = phy->dev;
struct {
u8 seq_num;
u8 is_ext_channel;
u8 rsv[2];
} __packed req = {
.seq_num = mvif->mt76.scan_seq_num,
};

if (test_and_clear_bit(MT76_HW_SCANNING, &phy->mt76->state)) {
struct cfg80211_scan_info info = {
.aborted = true,
};

ieee80211_scan_completed(phy->mt76->hw, &info);
}

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

int mt7615_mcu_sched_scan_req(struct mt7615_phy *phy,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *sreq)
{
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
struct ieee80211_channel **scan_list = sreq->channels;
struct mt7615_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy;
struct mt7615_mcu_scan_channel *chan;
struct mt7615_sched_scan_req *req;
struct cfg80211_match_set *match;
struct cfg80211_ssid *ssid;
struct sk_buff *skb;
int i;

if (!mt7615_firmware_offload(dev))
return -ENOTSUPP;

skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
sizeof(*req) + sreq->ie_len);
if (!skb)
return -ENOMEM;

mvif->mt76.scan_seq_num = (mvif->mt76.scan_seq_num + 1) & 0x7f;

req = (struct mt7615_sched_scan_req *)skb_put(skb, sizeof(*req));
req->version = 1;
req->seq_num = mvif->mt76.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(&dev->mt76, skb, MCU_CMD_SCHED_SCAN_REQ,
false);
}

int mt7615_mcu_sched_scan_enable(struct mt7615_phy *phy,
struct ieee80211_vif *vif,
bool enable)
{
struct mt7615_dev *dev = phy->dev;
struct {
u8 active; /* 0: enabled 1: disabled */
u8 rsv[3];
} __packed req = {
.active = !enable,
};

if (!mt7615_firmware_offload(dev))
return -ENOTSUPP;

if (enable)
set_bit(MT76_HW_SCHED_SCANNING, &phy->mt76->state);
else
clear_bit(MT76_HW_SCHED_SCANNING, &phy->mt76->state);

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

static int mt7615_find_freq_idx(const u16 *freqs, int n_freqs, u16 cur)
{
int i;
Expand Down Expand Up @@ -2878,9 +2670,10 @@ mt7615_mcu_set_wow_ctrl(struct mt7615_phy *phy, struct ieee80211_vif *vif,
if (wowlan->disconnect)
req.wow_ctrl_tlv.trigger |= BIT(2);
if (wowlan->nd_config) {
mt7615_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
mt76_connac_mcu_sched_scan_req(phy->mt76, vif,
wowlan->nd_config);
req.wow_ctrl_tlv.trigger |= BIT(5);
mt7615_mcu_sched_scan_enable(phy, vif, suspend);
mt76_connac_mcu_sched_scan_enable(phy->mt76, vif, suspend);
}

if (mt76_is_mmio(&dev->mt76))
Expand Down

0 comments on commit c888591

Please sign in to comment.