root/drivers/net/ethernet/intel/igc/igc_nvm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. igc_poll_eerd_eewr_done
  2. igc_acquire_nvm
  3. igc_release_nvm
  4. igc_read_nvm_eerd
  5. igc_read_mac_addr
  6. igc_validate_nvm_checksum
  7. igc_update_nvm_checksum

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright (c)  2018 Intel Corporation */
   3 
   4 #include "igc_mac.h"
   5 #include "igc_nvm.h"
   6 
   7 /**
   8  * igc_poll_eerd_eewr_done - Poll for EEPROM read/write completion
   9  * @hw: pointer to the HW structure
  10  * @ee_reg: EEPROM flag for polling
  11  *
  12  * Polls the EEPROM status bit for either read or write completion based
  13  * upon the value of 'ee_reg'.
  14  */
  15 static s32 igc_poll_eerd_eewr_done(struct igc_hw *hw, int ee_reg)
  16 {
  17         s32 ret_val = -IGC_ERR_NVM;
  18         u32 attempts = 100000;
  19         u32 i, reg = 0;
  20 
  21         for (i = 0; i < attempts; i++) {
  22                 if (ee_reg == IGC_NVM_POLL_READ)
  23                         reg = rd32(IGC_EERD);
  24                 else
  25                         reg = rd32(IGC_EEWR);
  26 
  27                 if (reg & IGC_NVM_RW_REG_DONE) {
  28                         ret_val = 0;
  29                         break;
  30                 }
  31 
  32                 udelay(5);
  33         }
  34 
  35         return ret_val;
  36 }
  37 
  38 /**
  39  * igc_acquire_nvm - Generic request for access to EEPROM
  40  * @hw: pointer to the HW structure
  41  *
  42  * Set the EEPROM access request bit and wait for EEPROM access grant bit.
  43  * Return successful if access grant bit set, else clear the request for
  44  * EEPROM access and return -IGC_ERR_NVM (-1).
  45  */
  46 s32 igc_acquire_nvm(struct igc_hw *hw)
  47 {
  48         s32 timeout = IGC_NVM_GRANT_ATTEMPTS;
  49         u32 eecd = rd32(IGC_EECD);
  50         s32 ret_val = 0;
  51 
  52         wr32(IGC_EECD, eecd | IGC_EECD_REQ);
  53         eecd = rd32(IGC_EECD);
  54 
  55         while (timeout) {
  56                 if (eecd & IGC_EECD_GNT)
  57                         break;
  58                 udelay(5);
  59                 eecd = rd32(IGC_EECD);
  60                 timeout--;
  61         }
  62 
  63         if (!timeout) {
  64                 eecd &= ~IGC_EECD_REQ;
  65                 wr32(IGC_EECD, eecd);
  66                 hw_dbg("Could not acquire NVM grant\n");
  67                 ret_val = -IGC_ERR_NVM;
  68         }
  69 
  70         return ret_val;
  71 }
  72 
  73 /**
  74  * igc_release_nvm - Release exclusive access to EEPROM
  75  * @hw: pointer to the HW structure
  76  *
  77  * Stop any current commands to the EEPROM and clear the EEPROM request bit.
  78  */
  79 void igc_release_nvm(struct igc_hw *hw)
  80 {
  81         u32 eecd;
  82 
  83         eecd = rd32(IGC_EECD);
  84         eecd &= ~IGC_EECD_REQ;
  85         wr32(IGC_EECD, eecd);
  86 }
  87 
  88 /**
  89  * igc_read_nvm_eerd - Reads EEPROM using EERD register
  90  * @hw: pointer to the HW structure
  91  * @offset: offset of word in the EEPROM to read
  92  * @words: number of words to read
  93  * @data: word read from the EEPROM
  94  *
  95  * Reads a 16 bit word from the EEPROM using the EERD register.
  96  */
  97 s32 igc_read_nvm_eerd(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
  98 {
  99         struct igc_nvm_info *nvm = &hw->nvm;
 100         u32 i, eerd = 0;
 101         s32 ret_val = 0;
 102 
 103         /* A check for invalid values:  offset too large, too many words,
 104          * and not enough words.
 105          */
 106         if (offset >= nvm->word_size || (words > (nvm->word_size - offset)) ||
 107             words == 0) {
 108                 hw_dbg("nvm parameter(s) out of bounds\n");
 109                 ret_val = -IGC_ERR_NVM;
 110                 goto out;
 111         }
 112 
 113         for (i = 0; i < words; i++) {
 114                 eerd = ((offset + i) << IGC_NVM_RW_ADDR_SHIFT) +
 115                         IGC_NVM_RW_REG_START;
 116 
 117                 wr32(IGC_EERD, eerd);
 118                 ret_val = igc_poll_eerd_eewr_done(hw, IGC_NVM_POLL_READ);
 119                 if (ret_val)
 120                         break;
 121 
 122                 data[i] = (rd32(IGC_EERD) >> IGC_NVM_RW_REG_DATA);
 123         }
 124 
 125 out:
 126         return ret_val;
 127 }
 128 
 129 /**
 130  * igc_read_mac_addr - Read device MAC address
 131  * @hw: pointer to the HW structure
 132  */
 133 s32 igc_read_mac_addr(struct igc_hw *hw)
 134 {
 135         u32 rar_high;
 136         u32 rar_low;
 137         u16 i;
 138 
 139         rar_high = rd32(IGC_RAH(0));
 140         rar_low = rd32(IGC_RAL(0));
 141 
 142         for (i = 0; i < IGC_RAL_MAC_ADDR_LEN; i++)
 143                 hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8));
 144 
 145         for (i = 0; i < IGC_RAH_MAC_ADDR_LEN; i++)
 146                 hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8));
 147 
 148         for (i = 0; i < ETH_ALEN; i++)
 149                 hw->mac.addr[i] = hw->mac.perm_addr[i];
 150 
 151         return 0;
 152 }
 153 
 154 /**
 155  * igc_validate_nvm_checksum - Validate EEPROM checksum
 156  * @hw: pointer to the HW structure
 157  *
 158  * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
 159  * and then verifies that the sum of the EEPROM is equal to 0xBABA.
 160  */
 161 s32 igc_validate_nvm_checksum(struct igc_hw *hw)
 162 {
 163         u16 checksum = 0;
 164         u16 i, nvm_data;
 165         s32 ret_val = 0;
 166 
 167         for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
 168                 ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
 169                 if (ret_val) {
 170                         hw_dbg("NVM Read Error\n");
 171                         goto out;
 172                 }
 173                 checksum += nvm_data;
 174         }
 175 
 176         if (checksum != (u16)NVM_SUM) {
 177                 hw_dbg("NVM Checksum Invalid\n");
 178                 ret_val = -IGC_ERR_NVM;
 179                 goto out;
 180         }
 181 
 182 out:
 183         return ret_val;
 184 }
 185 
 186 /**
 187  * igc_update_nvm_checksum - Update EEPROM checksum
 188  * @hw: pointer to the HW structure
 189  *
 190  * Updates the EEPROM checksum by reading/adding each word of the EEPROM
 191  * up to the checksum.  Then calculates the EEPROM checksum and writes the
 192  * value to the EEPROM.
 193  */
 194 s32 igc_update_nvm_checksum(struct igc_hw *hw)
 195 {
 196         u16 checksum = 0;
 197         u16 i, nvm_data;
 198         s32  ret_val;
 199 
 200         for (i = 0; i < NVM_CHECKSUM_REG; i++) {
 201                 ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
 202                 if (ret_val) {
 203                         hw_dbg("NVM Read Error while updating checksum.\n");
 204                         goto out;
 205                 }
 206                 checksum += nvm_data;
 207         }
 208         checksum = (u16)NVM_SUM - checksum;
 209         ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
 210         if (ret_val)
 211                 hw_dbg("NVM Write Error while updating checksum.\n");
 212 
 213 out:
 214         return ret_val;
 215 }

/* [<][>][^][v][top][bottom][index][help] */