mt76: move mac beacon routines in mt76x02-lib module
Move mt76x02_beacon mac routines in mt76x02_mac.c in order to be reused by mt76x0 driver adding AP support Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
5cbace02d8
commit
dc33b2512d
7 changed files with 135 additions and 129 deletions
|
|
@ -794,3 +794,126 @@ void mt76x02_mac_work(struct work_struct *work)
|
|||
MT_CALIBRATE_INTERVAL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_mac_work);
|
||||
|
||||
void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr)
|
||||
{
|
||||
idx &= 7;
|
||||
mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr));
|
||||
mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR,
|
||||
get_unaligned_le16(addr + 4));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_mac_set_bssid);
|
||||
|
||||
static int
|
||||
mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
|
||||
{
|
||||
int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
|
||||
struct mt76x02_txwi txwi;
|
||||
|
||||
if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
|
||||
return -ENOSPC;
|
||||
|
||||
mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
|
||||
|
||||
mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
|
||||
offset += sizeof(txwi);
|
||||
|
||||
mt76_wr_copy(dev, offset, skb->data, skb->len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
|
||||
int beacon_addr = mt76x02_beacon_offsets[bcn_idx];
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
/* Prevent corrupt transmissions during update */
|
||||
mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(bcn_idx));
|
||||
|
||||
if (skb) {
|
||||
ret = mt76x02_write_beacon(dev, beacon_addr, skb);
|
||||
if (!ret)
|
||||
dev->beacon_data_mask |= BIT(bcn_idx);
|
||||
} else {
|
||||
dev->beacon_data_mask &= ~BIT(bcn_idx);
|
||||
for (i = 0; i < beacon_len; i += 4)
|
||||
mt76_wr(dev, beacon_addr + i, 0);
|
||||
}
|
||||
|
||||
mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
bool force_update = false;
|
||||
int bcn_idx = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) {
|
||||
if (vif_idx == i) {
|
||||
force_update = !!dev->beacons[i] ^ !!skb;
|
||||
|
||||
if (dev->beacons[i])
|
||||
dev_kfree_skb(dev->beacons[i]);
|
||||
|
||||
dev->beacons[i] = skb;
|
||||
__mt76x02_mac_set_beacon(dev, bcn_idx, skb);
|
||||
} else if (force_update && dev->beacons[i]) {
|
||||
__mt76x02_mac_set_beacon(dev, bcn_idx,
|
||||
dev->beacons[i]);
|
||||
}
|
||||
|
||||
bcn_idx += !!dev->beacons[i];
|
||||
}
|
||||
|
||||
for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
|
||||
if (!(dev->beacon_data_mask & BIT(i)))
|
||||
break;
|
||||
|
||||
__mt76x02_mac_set_beacon(dev, i, NULL);
|
||||
}
|
||||
|
||||
mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
|
||||
bcn_idx - 1);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
|
||||
|
||||
void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
|
||||
u8 vif_idx, bool val)
|
||||
{
|
||||
u8 old_mask = dev->beacon_mask;
|
||||
bool en;
|
||||
u32 reg;
|
||||
|
||||
if (val) {
|
||||
dev->beacon_mask |= BIT(vif_idx);
|
||||
} else {
|
||||
dev->beacon_mask &= ~BIT(vif_idx);
|
||||
mt76x02_mac_set_beacon(dev, vif_idx, NULL);
|
||||
}
|
||||
|
||||
if (!!old_mask == !!dev->beacon_mask)
|
||||
return;
|
||||
|
||||
en = dev->beacon_mask;
|
||||
|
||||
mt76_rmw_field(dev, MT_INT_TIMER_EN, MT_INT_TIMER_EN_PRE_TBTT_EN, en);
|
||||
reg = MT_BEACON_TIME_CFG_BEACON_TX |
|
||||
MT_BEACON_TIME_CFG_TBTT_EN |
|
||||
MT_BEACON_TIME_CFG_TIMER_EN;
|
||||
mt76_rmw(dev, MT_BEACON_TIME_CFG, reg, reg * en);
|
||||
|
||||
if (en)
|
||||
mt76x02_irq_enable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
|
||||
else
|
||||
mt76x02_irq_disable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_enable);
|
||||
|
|
|
|||
|
|
@ -227,4 +227,10 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
|
|||
struct mt76_queue_entry *e, bool flush);
|
||||
void mt76x02_update_channel(struct mt76_dev *mdev);
|
||||
void mt76x02_mac_work(struct work_struct *work);
|
||||
|
||||
void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr);
|
||||
int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
|
||||
struct sk_buff *skb);
|
||||
void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev, u8 vif_idx,
|
||||
bool val);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,10 +26,5 @@ struct mt76x02_vif;
|
|||
int mt76x2_mac_start(struct mt76x02_dev *dev);
|
||||
void mt76x2_mac_stop(struct mt76x02_dev *dev, bool force);
|
||||
void mt76x2_mac_resume(struct mt76x02_dev *dev);
|
||||
void mt76x2_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr);
|
||||
|
||||
int mt76x2_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
|
||||
struct sk_buff *skb);
|
||||
void mt76x2_mac_set_beacon_enable(struct mt76x02_dev *dev, u8 vif_idx, bool val);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -153,8 +153,8 @@ static int mt76x2_mac_reset(struct mt76x02_dev *dev, bool hard)
|
|||
mt76x02_mac_shared_key_setup(dev, i, k, NULL);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
mt76x2_mac_set_bssid(dev, i, null_addr);
|
||||
mt76x2_mac_set_beacon(dev, i, NULL);
|
||||
mt76x02_mac_set_bssid(dev, i, null_addr);
|
||||
mt76x02_mac_set_beacon(dev, i, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
|
|
|
|||
|
|
@ -19,124 +19,6 @@
|
|||
#include "mcu.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
void mt76x2_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr)
|
||||
{
|
||||
idx &= 7;
|
||||
mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr));
|
||||
mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR,
|
||||
get_unaligned_le16(addr + 4));
|
||||
}
|
||||
|
||||
static int
|
||||
mt76_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
|
||||
{
|
||||
int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
|
||||
struct mt76x02_txwi txwi;
|
||||
|
||||
if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
|
||||
return -ENOSPC;
|
||||
|
||||
mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
|
||||
|
||||
mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
|
||||
offset += sizeof(txwi);
|
||||
|
||||
mt76_wr_copy(dev, offset, skb->data, skb->len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__mt76x2_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx, struct sk_buff *skb)
|
||||
{
|
||||
int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
|
||||
int beacon_addr = mt76x02_beacon_offsets[bcn_idx];
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
/* Prevent corrupt transmissions during update */
|
||||
mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(bcn_idx));
|
||||
|
||||
if (skb) {
|
||||
ret = mt76_write_beacon(dev, beacon_addr, skb);
|
||||
if (!ret)
|
||||
dev->beacon_data_mask |= BIT(bcn_idx);
|
||||
} else {
|
||||
dev->beacon_data_mask &= ~BIT(bcn_idx);
|
||||
for (i = 0; i < beacon_len; i += 4)
|
||||
mt76_wr(dev, beacon_addr + i, 0);
|
||||
}
|
||||
|
||||
mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mt76x2_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
bool force_update = false;
|
||||
int bcn_idx = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) {
|
||||
if (vif_idx == i) {
|
||||
force_update = !!dev->beacons[i] ^ !!skb;
|
||||
|
||||
if (dev->beacons[i])
|
||||
dev_kfree_skb(dev->beacons[i]);
|
||||
|
||||
dev->beacons[i] = skb;
|
||||
__mt76x2_mac_set_beacon(dev, bcn_idx, skb);
|
||||
} else if (force_update && dev->beacons[i]) {
|
||||
__mt76x2_mac_set_beacon(dev, bcn_idx, dev->beacons[i]);
|
||||
}
|
||||
|
||||
bcn_idx += !!dev->beacons[i];
|
||||
}
|
||||
|
||||
for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
|
||||
if (!(dev->beacon_data_mask & BIT(i)))
|
||||
break;
|
||||
|
||||
__mt76x2_mac_set_beacon(dev, i, NULL);
|
||||
}
|
||||
|
||||
mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
|
||||
bcn_idx - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mt76x2_mac_set_beacon_enable(struct mt76x02_dev *dev,
|
||||
u8 vif_idx, bool val)
|
||||
{
|
||||
u8 old_mask = dev->beacon_mask;
|
||||
bool en;
|
||||
u32 reg;
|
||||
|
||||
if (val) {
|
||||
dev->beacon_mask |= BIT(vif_idx);
|
||||
} else {
|
||||
dev->beacon_mask &= ~BIT(vif_idx);
|
||||
mt76x2_mac_set_beacon(dev, vif_idx, NULL);
|
||||
}
|
||||
|
||||
if (!!old_mask == !!dev->beacon_mask)
|
||||
return;
|
||||
|
||||
en = dev->beacon_mask;
|
||||
|
||||
mt76_rmw_field(dev, MT_INT_TIMER_EN, MT_INT_TIMER_EN_PRE_TBTT_EN, en);
|
||||
reg = MT_BEACON_TIME_CFG_BEACON_TX |
|
||||
MT_BEACON_TIME_CFG_TBTT_EN |
|
||||
MT_BEACON_TIME_CFG_TIMER_EN;
|
||||
mt76_rmw(dev, MT_BEACON_TIME_CFG, reg, reg * en);
|
||||
|
||||
if (en)
|
||||
mt76x02_irq_enable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
|
||||
else
|
||||
mt76x02_irq_disable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
|
||||
}
|
||||
|
||||
void mt76x2_mac_set_tx_protection(struct mt76x02_dev *dev, u32 val)
|
||||
{
|
||||
u32 data = 0;
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
if (changed & BSS_CHANGED_BSSID)
|
||||
mt76x2_mac_set_bssid(dev, mvif->idx, info->bssid);
|
||||
mt76x02_mac_set_bssid(dev, mvif->idx, info->bssid);
|
||||
|
||||
if (changed & BSS_CHANGED_BEACON_INT) {
|
||||
mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
|
||||
|
|
@ -149,8 +149,8 @@ mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
|
||||
if (changed & BSS_CHANGED_BEACON_ENABLED) {
|
||||
tasklet_disable(&dev->pre_tbtt_tasklet);
|
||||
mt76x2_mac_set_beacon_enable(dev, mvif->idx,
|
||||
info->enable_beacon);
|
||||
mt76x02_mac_set_beacon_enable(dev, mvif->idx,
|
||||
info->enable_beacon);
|
||||
tasklet_enable(&dev->pre_tbtt_tasklet);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ mt76x2_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
|||
if (!skb)
|
||||
return;
|
||||
|
||||
mt76x2_mac_set_beacon(dev, mvif->idx, skb);
|
||||
mt76x02_mac_set_beacon(dev, mvif->idx, skb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue