Message ID | 20240926032440.15978-1-shayne.chen@mediatek.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Felix Fietkau |
Headers | show |
Series | [1/3] wifi: mt76: mt7996: extend flexibility of mt7996_mcu_get_eeprom() | expand |
On Thu, Sep 26, 2024 at 11:24:38AM +0800, Shayne Chen wrote: > Support passing customized buffer pointer and length to > mt7996_mcu_get_eeprom(). > > This is the preparation for adding more variants support which needs to > prefetch FEM module from efuse, and also fixes potential OOB issue when > reading the last efuse block. > > Co-developed-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> > Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> > Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> Tested-by: Daniel Golle <daniel@makrotopia.org> > --- > drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c | 9 +++++++-- > drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 14 ++++++++++---- > drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- > 3 files changed, 18 insertions(+), 7 deletions(-) > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c > index 4a8237118287..861aba68a725 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c > @@ -86,8 +86,13 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev) > /* read eeprom data from efuse */ > block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size); > for (i = 0; i < block_num; i++) { > - ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size); > - if (ret < 0) > + u32 len = eeprom_blk_size; > + > + if (i == block_num - 1) > + len = MT7996_EEPROM_SIZE % eeprom_blk_size; > + ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size, > + NULL, len); > + if (ret && ret != -EINVAL) > return ret; > } > } > diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c > index 327337b31279..fa7832f625d7 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c > @@ -3548,7 +3548,7 @@ int mt7996_mcu_set_eeprom(struct mt7996_dev *dev) > &req, sizeof(req), true); > } > > -int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset) > +int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *buf, u32 buf_len) > { > struct { > u8 _rsv[4]; > @@ -3577,15 +3577,21 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset) > valid = le32_to_cpu(*(__le32 *)(skb->data + 16)); > if (valid) { > u32 addr = le32_to_cpu(*(__le32 *)(skb->data + 12)); > - u8 *buf = (u8 *)dev->mt76.eeprom.data + addr; > + > + if (!buf) > + buf = (u8 *)dev->mt76.eeprom.data + addr; > + if (!buf_len || buf_len > MT7996_EEPROM_BLOCK_SIZE) > + buf_len = MT7996_EEPROM_BLOCK_SIZE; > > skb_pull(skb, 48); > - memcpy(buf, skb->data, MT7996_EEPROM_BLOCK_SIZE); > + memcpy(buf, skb->data, buf_len); > + } else { > + ret = -EINVAL; > } > > dev_kfree_skb(skb); > > - return 0; > + return ret; > } > > int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num) > diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h > index ab8c9070630b..55aa5f6ab77d 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h > +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h > @@ -476,7 +476,7 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev, > int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif, > struct ieee80211_sta *sta, void *data, u32 field); > int mt7996_mcu_set_eeprom(struct mt7996_dev *dev); > -int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset); > +int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *buf, u32 buf_len); > int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num); > int mt7996_mcu_get_chip_config(struct mt7996_dev *dev, u32 *cap); > int mt7996_mcu_set_ser(struct mt7996_dev *dev, u8 action, u8 set, u8 band); > -- > 2.39.2 >
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c index 4a8237118287..861aba68a725 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c @@ -86,8 +86,13 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev) /* read eeprom data from efuse */ block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size); for (i = 0; i < block_num; i++) { - ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size); - if (ret < 0) + u32 len = eeprom_blk_size; + + if (i == block_num - 1) + len = MT7996_EEPROM_SIZE % eeprom_blk_size; + ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size, + NULL, len); + if (ret && ret != -EINVAL) return ret; } } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index 327337b31279..fa7832f625d7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -3548,7 +3548,7 @@ int mt7996_mcu_set_eeprom(struct mt7996_dev *dev) &req, sizeof(req), true); } -int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset) +int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *buf, u32 buf_len) { struct { u8 _rsv[4]; @@ -3577,15 +3577,21 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset) valid = le32_to_cpu(*(__le32 *)(skb->data + 16)); if (valid) { u32 addr = le32_to_cpu(*(__le32 *)(skb->data + 12)); - u8 *buf = (u8 *)dev->mt76.eeprom.data + addr; + + if (!buf) + buf = (u8 *)dev->mt76.eeprom.data + addr; + if (!buf_len || buf_len > MT7996_EEPROM_BLOCK_SIZE) + buf_len = MT7996_EEPROM_BLOCK_SIZE; skb_pull(skb, 48); - memcpy(buf, skb->data, MT7996_EEPROM_BLOCK_SIZE); + memcpy(buf, skb->data, buf_len); + } else { + ret = -EINVAL; } dev_kfree_skb(skb); - return 0; + return ret; } int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index ab8c9070630b..55aa5f6ab77d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -476,7 +476,7 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev, int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, void *data, u32 field); int mt7996_mcu_set_eeprom(struct mt7996_dev *dev); -int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset); +int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *buf, u32 buf_len); int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num); int mt7996_mcu_get_chip_config(struct mt7996_dev *dev, u32 *cap); int mt7996_mcu_set_ser(struct mt7996_dev *dev, u8 action, u8 set, u8 band);