aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7915/mmio.c')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mmio.c162
1 files changed, 46 insertions, 116 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
index e7d8e03f826f..d6ecd698cdcd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
@@ -490,6 +490,11 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr)
return dev->reg.map[i].maps + ofs;
}
+ return 0;
+}
+
+static u32 __mt7915_reg_remap_addr(struct mt7915_dev *dev, u32 addr)
+{
if ((addr >= MT_INFRA_BASE && addr < MT_WFSYS0_PHY_START) ||
(addr >= MT_WFSYS0_PHY_START && addr < MT_WFSYS1_PHY_START) ||
(addr >= MT_WFSYS1_PHY_START && addr <= MT_WFSYS1_PHY_END))
@@ -514,133 +519,63 @@ void mt7915_memcpy_fromio(struct mt7915_dev *dev, void *buf, u32 offset,
{
u32 addr = __mt7915_reg_addr(dev, offset);
- memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len);
+ if (addr) {
+ memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len);
+ return;
+ }
+
+ spin_lock_bh(&dev->reg_lock);
+ memcpy_fromio(buf, dev->mt76.mmio.regs +
+ __mt7915_reg_remap_addr(dev, offset), len);
+ spin_unlock_bh(&dev->reg_lock);
}
static u32 mt7915_rr(struct mt76_dev *mdev, u32 offset)
{
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
- u32 addr = __mt7915_reg_addr(dev, offset);
+ u32 addr = __mt7915_reg_addr(dev, offset), val;
- return dev->bus_ops->rr(mdev, addr);
-}
+ if (addr)
+ return dev->bus_ops->rr(mdev, addr);
-static void mt7915_wr(struct mt76_dev *mdev, u32 offset, u32 val)
-{
- struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
- u32 addr = __mt7915_reg_addr(dev, offset);
+ spin_lock_bh(&dev->reg_lock);
+ val = dev->bus_ops->rr(mdev, __mt7915_reg_remap_addr(dev, offset));
+ spin_unlock_bh(&dev->reg_lock);
- dev->bus_ops->wr(mdev, addr, val);
+ return val;
}
-static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+static void mt7915_wr(struct mt76_dev *mdev, u32 offset, u32 val)
{
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
u32 addr = __mt7915_reg_addr(dev, offset);
- return dev->bus_ops->rmw(mdev, addr, mask, val);
-}
-
-#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
-{
- struct mt7915_dev *dev;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
-
- spin_lock_bh(&dev->mt76.token_lock);
- dev->mt76.token_size = wed->wlan.token_start;
- spin_unlock_bh(&dev->mt76.token_lock);
-
- return !wait_event_timeout(dev->mt76.tx_wait,
- !dev->mt76.wed_token_count, HZ);
-}
-
-static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
-{
- struct mt7915_dev *dev;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
-
- spin_lock_bh(&dev->mt76.token_lock);
- dev->mt76.token_size = MT7915_TOKEN_SIZE;
- spin_unlock_bh(&dev->mt76.token_lock);
-}
-
-static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
-{
- struct mt7915_dev *dev;
- int i;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
- for (i = 0; i < dev->mt76.rx_token_size; i++) {
- struct mt76_txwi_cache *t;
-
- t = mt76_rx_token_release(&dev->mt76, i);
- if (!t || !t->ptr)
- continue;
-
- mt76_put_page_pool_buf(t->ptr, false);
- t->ptr = NULL;
-
- mt76_put_rxwi(&dev->mt76, t);
+ if (addr) {
+ dev->bus_ops->wr(mdev, addr, val);
+ return;
}
- mt76_free_pending_rxwi(&dev->mt76);
+ spin_lock_bh(&dev->reg_lock);
+ dev->bus_ops->wr(mdev, __mt7915_reg_remap_addr(dev, offset), val);
+ spin_unlock_bh(&dev->reg_lock);
}
-static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
{
- struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
- struct mt76_txwi_cache *t = NULL;
- struct mt7915_dev *dev;
- struct mt76_queue *q;
- int i, len;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
- q = &dev->mt76.q_rx[MT_RXQ_MAIN];
- len = SKB_WITH_OVERHEAD(q->buf_size);
-
- for (i = 0; i < size; i++) {
- enum dma_data_direction dir;
- dma_addr_t addr;
- u32 offset;
- int token;
- void *buf;
-
- t = mt76_get_rxwi(&dev->mt76);
- if (!t)
- goto unmap;
-
- buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
- if (!buf)
- goto unmap;
-
- addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
- dir = page_pool_get_dma_dir(q->page_pool);
- dma_sync_single_for_device(dev->mt76.dma_dev, addr, len, dir);
-
- desc->buf0 = cpu_to_le32(addr);
- token = mt76_rx_token_consume(&dev->mt76, buf, t, addr);
- if (token < 0) {
- mt76_put_page_pool_buf(buf, false);
- goto unmap;
- }
+ struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
+ u32 addr = __mt7915_reg_addr(dev, offset);
- desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
- token));
- desc++;
- }
+ if (addr)
+ return dev->bus_ops->rmw(mdev, addr, mask, val);
- return 0;
+ spin_lock_bh(&dev->reg_lock);
+ val = dev->bus_ops->rmw(mdev, __mt7915_reg_remap_addr(dev, offset), mask, val);
+ spin_unlock_bh(&dev->reg_lock);
-unmap:
- if (t)
- mt76_put_rxwi(&dev->mt76, t);
- mt7915_mmio_wed_release_rx_buf(wed);
- return -ENOMEM;
+ return val;
}
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
struct mtk_wed_wo_rx_stats *stats)
{
@@ -694,13 +629,6 @@ out:
return ret;
}
-
-static void mt7915_mmio_wed_reset_complete(struct mtk_wed_device *wed)
-{
- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
-
- complete(&dev->mmio.wed_reset_complete);
-}
#endif
int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
@@ -742,7 +670,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
if (!res)
- return -ENOMEM;
+ return 0;
wed->wlan.platform_dev = plat_dev;
wed->wlan.bus_type = MTK_WED_BUS_AXI;
@@ -778,13 +706,13 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
}
wed->wlan.init_buf = mt7915_wed_init_buf;
- wed->wlan.offload_enable = mt7915_mmio_wed_offload_enable;
- wed->wlan.offload_disable = mt7915_mmio_wed_offload_disable;
- wed->wlan.init_rx_buf = mt7915_mmio_wed_init_rx_buf;
- wed->wlan.release_rx_buf = mt7915_mmio_wed_release_rx_buf;
+ wed->wlan.offload_enable = mt76_wed_offload_enable;
+ wed->wlan.offload_disable = mt76_wed_offload_disable;
+ wed->wlan.init_rx_buf = mt76_wed_init_rx_buf;
+ wed->wlan.release_rx_buf = mt76_wed_release_rx_buf;
wed->wlan.update_wo_rx_stats = mt7915_mmio_wed_update_rx_stats;
wed->wlan.reset = mt7915_mmio_wed_reset;
- wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete;
+ wed->wlan.reset_complete = mt76_wed_reset_complete;
dev->mt76.rx_token_size = wed->wlan.rx_npkt;
@@ -813,6 +741,7 @@ static int mt7915_mmio_init(struct mt76_dev *mdev,
dev = container_of(mdev, struct mt7915_dev, mt76);
mt76_mmio_init(&dev->mt76, mem_base);
+ spin_lock_init(&dev->reg_lock);
switch (device_id) {
case 0x7915:
@@ -1064,4 +993,5 @@ static void __exit mt7915_exit(void)
module_init(mt7915_init);
module_exit(mt7915_exit);
+MODULE_DESCRIPTION("MediaTek MT7915E MMIO helpers");
MODULE_LICENSE("Dual BSD/GPL");