lkml.org 
[lkml]   [2024]   [Mar]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 6.8 42/68] wifi: mt76: mt7915: add locking for accessing mapped registers
    Date
    From: Shayne Chen <shayne.chen@mediatek.com>

    [ Upstream commit 0937f95ab07af6e663ae932d592f630d9eb591da ]

    Sicne the mapping is global, mapped register access needs to be protected
    against concurrent access, otherwise a race condition might cause the reads
    or writes to go towards the wrong register

    Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
    Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
    Signed-off-by: Felix Fietkau <nbd@nbd.name>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    .../net/wireless/mediatek/mt76/mt7915/mmio.c | 45 ++++++++++++++++---
    .../wireless/mediatek/mt76/mt7915/mt7915.h | 1 +
    2 files changed, 41 insertions(+), 5 deletions(-)

    diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
    index 3039f53e22454..dceb505987b19 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,15 +519,30 @@ 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);
    +
    + spin_lock_bh(&dev->reg_lock);
    + val = dev->bus_ops->rr(mdev, __mt7915_reg_remap_addr(dev, offset));
    + spin_unlock_bh(&dev->reg_lock);
    +
    + return val;
    }

    static void mt7915_wr(struct mt76_dev *mdev, u32 offset, u32 val)
    @@ -530,7 +550,14 @@ 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);

    - dev->bus_ops->wr(mdev, addr, val);
    + if (addr) {
    + dev->bus_ops->wr(mdev, addr, val);
    + return;
    + }
    +
    + 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_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
    @@ -538,7 +565,14 @@ 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);

    - return dev->bus_ops->rmw(mdev, addr, mask, val);
    + if (addr)
    + return dev->bus_ops->rmw(mdev, addr, mask, val);
    +
    + 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);
    +
    + return val;
    }

    #ifdef CONFIG_NET_MEDIATEK_SOC_WED
    @@ -707,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:
    diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
    index 4727d9c7b11de..6e79bc65f5a51 100644
    --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
    +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
    @@ -287,6 +287,7 @@ struct mt7915_dev {

    struct list_head sta_rc_list;
    struct list_head twt_list;
    + spinlock_t reg_lock;

    u32 hw_pattern;

    --
    2.43.0

    \
     
     \ /
      Last update: 2024-05-27 16:15    [W:7.379 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site