|
@@ -351,38 +351,56 @@ static int i40e_get_eeprom(struct net_device *netdev,
|
|
{
|
|
{
|
|
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
|
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
|
struct i40e_hw *hw = &np->vsi->back->hw;
|
|
struct i40e_hw *hw = &np->vsi->back->hw;
|
|
- int first_word, last_word;
|
|
|
|
- u16 i, eeprom_len;
|
|
|
|
- u16 *eeprom_buff;
|
|
|
|
- int ret_val = 0;
|
|
|
|
-
|
|
|
|
|
|
+ struct i40e_pf *pf = np->vsi->back;
|
|
|
|
+ int ret_val = 0, len;
|
|
|
|
+ u8 *eeprom_buff;
|
|
|
|
+ u16 i, sectors;
|
|
|
|
+ bool last;
|
|
|
|
+#define I40E_NVM_SECTOR_SIZE 4096
|
|
if (eeprom->len == 0)
|
|
if (eeprom->len == 0)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
|
|
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
|
|
|
|
|
|
- first_word = eeprom->offset >> 1;
|
|
|
|
- last_word = (eeprom->offset + eeprom->len - 1) >> 1;
|
|
|
|
- eeprom_len = last_word - first_word + 1;
|
|
|
|
-
|
|
|
|
- eeprom_buff = kmalloc(sizeof(u16) * eeprom_len, GFP_KERNEL);
|
|
|
|
|
|
+ eeprom_buff = kzalloc(eeprom->len, GFP_KERNEL);
|
|
if (!eeprom_buff)
|
|
if (!eeprom_buff)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
- ret_val = i40e_read_nvm_buffer(hw, first_word, &eeprom_len,
|
|
|
|
- eeprom_buff);
|
|
|
|
- if (eeprom_len == 0) {
|
|
|
|
- kfree(eeprom_buff);
|
|
|
|
- return -EACCES;
|
|
|
|
|
|
+ ret_val = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
|
|
|
|
+ if (ret_val) {
|
|
|
|
+ dev_info(&pf->pdev->dev,
|
|
|
|
+ "Failed Acquiring NVM resource for read err=%d status=0x%x\n",
|
|
|
|
+ ret_val, hw->aq.asq_last_status);
|
|
|
|
+ goto free_buff;
|
|
}
|
|
}
|
|
|
|
|
|
- /* Device's eeprom is always little-endian, word addressable */
|
|
|
|
- for (i = 0; i < eeprom_len; i++)
|
|
|
|
- le16_to_cpus(&eeprom_buff[i]);
|
|
|
|
|
|
+ sectors = eeprom->len / I40E_NVM_SECTOR_SIZE;
|
|
|
|
+ sectors += (eeprom->len % I40E_NVM_SECTOR_SIZE) ? 1 : 0;
|
|
|
|
+ len = I40E_NVM_SECTOR_SIZE;
|
|
|
|
+ last = false;
|
|
|
|
+ for (i = 0; i < sectors; i++) {
|
|
|
|
+ if (i == (sectors - 1)) {
|
|
|
|
+ len = eeprom->len - (I40E_NVM_SECTOR_SIZE * i);
|
|
|
|
+ last = true;
|
|
|
|
+ }
|
|
|
|
+ ret_val = i40e_aq_read_nvm(hw, 0x0,
|
|
|
|
+ eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
|
|
|
|
+ len,
|
|
|
|
+ (u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
|
|
|
|
+ last, NULL);
|
|
|
|
+ if (ret_val) {
|
|
|
|
+ dev_info(&pf->pdev->dev,
|
|
|
|
+ "read NVM failed err=%d status=0x%x\n",
|
|
|
|
+ ret_val, hw->aq.asq_last_status);
|
|
|
|
+ goto release_nvm;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
|
|
|
|
|
|
+release_nvm:
|
|
|
|
+ i40e_release_nvm(hw);
|
|
|
|
+ memcpy(bytes, (u8 *)eeprom_buff, eeprom->len);
|
|
|
|
+free_buff:
|
|
kfree(eeprom_buff);
|
|
kfree(eeprom_buff);
|
|
-
|
|
|
|
return ret_val;
|
|
return ret_val;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -390,8 +408,14 @@ static int i40e_get_eeprom_len(struct net_device *netdev)
|
|
{
|
|
{
|
|
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
|
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
|
struct i40e_hw *hw = &np->vsi->back->hw;
|
|
struct i40e_hw *hw = &np->vsi->back->hw;
|
|
-
|
|
|
|
- return hw->nvm.sr_size * 2;
|
|
|
|
|
|
+ u32 val;
|
|
|
|
+
|
|
|
|
+ val = (rd32(hw, I40E_GLPCI_LBARCTRL)
|
|
|
|
+ & I40E_GLPCI_LBARCTRL_FL_SIZE_MASK)
|
|
|
|
+ >> I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT;
|
|
|
|
+ /* register returns value in power of 2, 64Kbyte chunks. */
|
|
|
|
+ val = (64 * 1024) * (1 << val);
|
|
|
|
+ return val;
|
|
}
|
|
}
|
|
|
|
|
|
static void i40e_get_drvinfo(struct net_device *netdev,
|
|
static void i40e_get_drvinfo(struct net_device *netdev,
|