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@xxxxxxxxxxxx> > Signed-off-by: StanleyYP Wang <StanleyYP.Wang@xxxxxxxxxxxx> > Signed-off-by: Shayne Chen <shayne.chen@xxxxxxxxxxxx> Tested-by: Daniel Golle <daniel@xxxxxxxxxxxxxx> > --- > 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 >