| From 7b50ef5c4c3768652f1c4bcdb14e8ee0639c8b7f Mon Sep 17 00:00:00 2001 |
| From: Shayne Chen <shayne.chen@mediatek.com> |
| Date: Tue, 15 Aug 2023 17:28:30 +0800 |
| Subject: [PATCH 05/76] wifi: mt76: mt7915: rework mmio access flow |
| |
| Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> |
| Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com> |
| --- |
| mt7915/mmio.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- |
| mt7915/mt7915.h | 1 + |
| 2 files changed, 45 insertions(+), 5 deletions(-) |
| |
| diff --git a/mt7915/mmio.c b/mt7915/mmio.c |
| index aff4f21..bd9e01d 100644 |
| --- a/mt7915/mmio.c |
| +++ b/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)) |
| @@ -513,32 +518,65 @@ void mt7915_memcpy_fromio(struct mt7915_dev *dev, void *buf, u32 offset, |
| size_t len) |
| { |
| u32 addr = __mt7915_reg_addr(dev, offset); |
| + unsigned long flags; |
| |
| - memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len); |
| + if (addr) { |
| + memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len); |
| + return; |
| + } |
| + |
| + spin_lock_irqsave(&dev->reg_lock, flags); |
| + memcpy_fromio(buf, dev->mt76.mmio.regs + |
| + __mt7915_reg_remap_addr(dev, offset), len); |
| + spin_unlock_irqrestore(&dev->reg_lock, flags); |
| } |
| |
| 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; |
| + unsigned long flags; |
| |
| - return dev->bus_ops->rr(mdev, addr); |
| + if (addr) |
| + return dev->bus_ops->rr(mdev, addr); |
| + |
| + spin_lock_irqsave(&dev->reg_lock, flags); |
| + val = dev->bus_ops->rr(mdev, __mt7915_reg_remap_addr(dev, offset)); |
| + spin_unlock_irqrestore(&dev->reg_lock, flags); |
| + |
| + return 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); |
| + unsigned long flags; |
| |
| - dev->bus_ops->wr(mdev, addr, val); |
| + if (addr) { |
| + dev->bus_ops->wr(mdev, addr, val); |
| + return; |
| + } |
| + |
| + spin_lock_irqsave(&dev->reg_lock, flags); |
| + dev->bus_ops->wr(mdev, __mt7915_reg_remap_addr(dev, offset), val); |
| + spin_unlock_irqrestore(&dev->reg_lock, flags); |
| } |
| |
| static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) |
| { |
| struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); |
| u32 addr = __mt7915_reg_addr(dev, offset); |
| + unsigned long flags; |
| + |
| + if (addr) |
| + return dev->bus_ops->rmw(mdev, addr, mask, val); |
| + |
| + spin_lock_irqsave(&dev->reg_lock, flags); |
| + val = dev->bus_ops->rmw(mdev, __mt7915_reg_remap_addr(dev, offset), mask, val); |
| + spin_unlock_irqrestore(&dev->reg_lock, flags); |
| |
| - return dev->bus_ops->rmw(mdev, addr, mask, val); |
| + return val; |
| } |
| |
| #ifdef CONFIG_NET_MEDIATEK_SOC_WED |
| @@ -707,6 +745,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: |
| diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h |
| index 4293385..35458ec 100644 |
| --- a/mt7915/mt7915.h |
| +++ b/mt7915/mt7915.h |
| @@ -292,6 +292,7 @@ struct mt7915_dev { |
| |
| struct list_head sta_rc_list; |
| struct list_head twt_list; |
| + spinlock_t reg_lock; |
| |
| u32 hw_pattern; |
| |
| -- |
| 2.18.0 |
| |