LCOV - code coverage report
Current view: top level - drivers/net/txgbe/base - txgbe_eeprom.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 136 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 14 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 62 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2015-2020 Beijing WangXun Technology Co., Ltd.
       3                 :            :  * Copyright(c) 2010-2017 Intel Corporation
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "txgbe_hw.h"
       7                 :            : #include "txgbe_mng.h"
       8                 :            : #include "txgbe_eeprom.h"
       9                 :            : 
      10                 :            : /**
      11                 :            :  *  txgbe_init_eeprom_params - Initialize EEPROM params
      12                 :            :  *  @hw: pointer to hardware structure
      13                 :            :  *
      14                 :            :  *  Initializes the EEPROM parameters txgbe_rom_info within the
      15                 :            :  *  txgbe_hw struct in order to set up EEPROM access.
      16                 :            :  **/
      17                 :          0 : s32 txgbe_init_eeprom_params(struct txgbe_hw *hw)
      18                 :            : {
      19                 :            :         struct txgbe_rom_info *eeprom = &hw->rom;
      20                 :            :         u32 eec;
      21                 :            :         u16 eeprom_size;
      22                 :            :         int err = 0;
      23                 :            : 
      24         [ #  # ]:          0 :         if (eeprom->type != txgbe_eeprom_unknown)
      25                 :            :                 return 0;
      26                 :            : 
      27                 :          0 :         eeprom->type = txgbe_eeprom_none;
      28                 :            :         /* Set default semaphore delay to 10ms which is a well
      29                 :            :          * tested value
      30                 :            :          */
      31                 :          0 :         eeprom->semaphore_delay = 10; /*ms*/
      32                 :            :         /* Clear EEPROM page size, it will be initialized as needed */
      33                 :          0 :         eeprom->word_page_size = 0;
      34                 :            : 
      35                 :            :         /*
      36                 :            :          * Check for EEPROM present first.
      37                 :            :          * If not present leave as none
      38                 :            :          */
      39                 :            :         eec = rd32(hw, TXGBE_SPISTAT);
      40         [ #  # ]:          0 :         if (!(eec & TXGBE_SPISTAT_BPFLASH)) {
      41                 :          0 :                 eeprom->type = txgbe_eeprom_flash;
      42                 :            : 
      43                 :            :                 /*
      44                 :            :                  * SPI EEPROM is assumed here.  This code would need to
      45                 :            :                  * change if a future EEPROM is not SPI.
      46                 :            :                  */
      47                 :            :                 eeprom_size = 4096;
      48                 :          0 :                 eeprom->word_size = eeprom_size >> 1;
      49                 :            :         }
      50                 :            : 
      51                 :          0 :         eeprom->address_bits = 16;
      52                 :            : 
      53                 :          0 :         err = eeprom->read32(hw, TXGBE_SW_REGION_PTR << 1, &eeprom->sw_addr);
      54         [ #  # ]:          0 :         if (err) {
      55                 :          0 :                 DEBUGOUT("EEPROM read failed.");
      56                 :          0 :                 return err;
      57                 :            :         }
      58                 :            : 
      59                 :          0 :         DEBUGOUT("eeprom params: type = %d, size = %d, address bits: %d %d",
      60                 :            :                   eeprom->type, eeprom->word_size,
      61                 :            :                   eeprom->address_bits, eeprom->sw_addr);
      62                 :            : 
      63                 :          0 :         return 0;
      64                 :            : }
      65                 :            : 
      66                 :            : /**
      67                 :            :  *  txgbe_get_eeprom_semaphore - Get hardware semaphore
      68                 :            :  *  @hw: pointer to hardware structure
      69                 :            :  *
      70                 :            :  *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method
      71                 :            :  **/
      72                 :          0 : s32 txgbe_get_eeprom_semaphore(struct txgbe_hw *hw)
      73                 :            : {
      74                 :            :         s32 status = TXGBE_ERR_EEPROM;
      75                 :            :         u32 timeout = 2000;
      76                 :            :         u32 i;
      77                 :            :         u32 swsm;
      78                 :            : 
      79                 :            :         /* Get SMBI software semaphore between device drivers first */
      80         [ #  # ]:          0 :         for (i = 0; i < timeout; i++) {
      81                 :            :                 /*
      82                 :            :                  * If the SMBI bit is 0 when we read it, then the bit will be
      83                 :            :                  * set and we have the semaphore
      84                 :            :                  */
      85                 :            :                 swsm = rd32(hw, TXGBE_SWSEM);
      86         [ #  # ]:          0 :                 if (!(swsm & TXGBE_SWSEM_PF)) {
      87                 :            :                         status = 0;
      88                 :            :                         break;
      89                 :            :                 }
      90                 :          0 :                 usec_delay(50);
      91                 :            :         }
      92                 :            : 
      93         [ #  # ]:          0 :         if (i == timeout) {
      94                 :          0 :                 DEBUGOUT("Driver can't access the eeprom - SMBI Semaphore not granted.");
      95                 :            :                 /*
      96                 :            :                  * this release is particularly important because our attempts
      97                 :            :                  * above to get the semaphore may have succeeded, and if there
      98                 :            :                  * was a timeout, we should unconditionally clear the semaphore
      99                 :            :                  * bits to free the driver to make progress
     100                 :            :                  */
     101                 :          0 :                 txgbe_release_eeprom_semaphore(hw);
     102                 :            : 
     103                 :          0 :                 usec_delay(50);
     104                 :            :                 /*
     105                 :            :                  * one last try
     106                 :            :                  * If the SMBI bit is 0 when we read it, then the bit will be
     107                 :            :                  * set and we have the semaphore
     108                 :            :                  */
     109                 :            :                 swsm = rd32(hw, TXGBE_SWSEM);
     110         [ #  # ]:          0 :                 if (!(swsm & TXGBE_SWSEM_PF))
     111                 :            :                         status = 0;
     112                 :            :         }
     113                 :            : 
     114                 :          0 :         return status;
     115                 :            : }
     116                 :            : 
     117                 :            : /**
     118                 :            :  *  txgbe_release_eeprom_semaphore - Release hardware semaphore
     119                 :            :  *  @hw: pointer to hardware structure
     120                 :            :  *
     121                 :            :  *  This function clears hardware semaphore bits.
     122                 :            :  **/
     123                 :          0 : void txgbe_release_eeprom_semaphore(struct txgbe_hw *hw)
     124                 :            : {
     125                 :            :         wr32m(hw, TXGBE_SWSEM, TXGBE_SWSEM_PF, 0);
     126                 :            :         txgbe_flush(hw);
     127                 :          0 : }
     128                 :            : 
     129                 :            : /**
     130                 :            :  *  txgbe_ee_read - Read EEPROM word using a host interface cmd
     131                 :            :  *  @hw: pointer to hardware structure
     132                 :            :  *  @offset: offset of  word in the EEPROM to read
     133                 :            :  *  @data: word read from the EEPROM
     134                 :            :  *
     135                 :            :  *  Reads a 16 bit word from the EEPROM using the hostif.
     136                 :            :  **/
     137                 :          0 : s32 txgbe_ee_read16(struct txgbe_hw *hw, u32 offset,
     138                 :            :                               u16 *data)
     139                 :            : {
     140                 :            :         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
     141                 :          0 :         u32 addr = (offset << 1);
     142                 :            :         int err;
     143                 :            : 
     144                 :          0 :         err = hw->mac.acquire_swfw_sync(hw, mask);
     145         [ #  # ]:          0 :         if (err)
     146                 :            :                 return err;
     147                 :            : 
     148                 :          0 :         err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2);
     149                 :            : 
     150                 :          0 :         hw->mac.release_swfw_sync(hw, mask);
     151                 :            : 
     152                 :          0 :         return err;
     153                 :            : }
     154                 :            : 
     155                 :            : /**
     156                 :            :  *  txgbe_ee_readw_buffer- Read EEPROM word(s) using hostif
     157                 :            :  *  @hw: pointer to hardware structure
     158                 :            :  *  @offset: offset of  word in the EEPROM to read
     159                 :            :  *  @words: number of words
     160                 :            :  *  @data: word(s) read from the EEPROM
     161                 :            :  *
     162                 :            :  *  Reads a 16 bit word(s) from the EEPROM using the hostif.
     163                 :            :  **/
     164                 :          0 : s32 txgbe_ee_readw_buffer(struct txgbe_hw *hw,
     165                 :            :                                      u32 offset, u32 words, void *data)
     166                 :            : {
     167                 :            :         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
     168                 :          0 :         u32 addr = (offset << 1);
     169                 :          0 :         u32 len = (words << 1);
     170                 :            :         u8 *buf = (u8 *)data;
     171                 :            :         int err;
     172                 :            : 
     173                 :          0 :         err = hw->mac.acquire_swfw_sync(hw, mask);
     174         [ #  # ]:          0 :         if (err)
     175                 :            :                 return err;
     176                 :            : 
     177         [ #  # ]:          0 :         while (len) {
     178                 :          0 :                 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
     179                 :            :                                 ? len : TXGBE_PMMBX_DATA_SIZE);
     180                 :            : 
     181                 :          0 :                 err = txgbe_hic_sr_read(hw, addr, buf, seg);
     182         [ #  # ]:          0 :                 if (err)
     183                 :            :                         break;
     184                 :            : 
     185                 :          0 :                 len -= seg;
     186                 :          0 :                 addr += seg;
     187                 :          0 :                 buf += seg;
     188                 :            :         }
     189                 :            : 
     190                 :          0 :         hw->mac.release_swfw_sync(hw, mask);
     191                 :          0 :         return err;
     192                 :            : }
     193                 :            : 
     194                 :            : 
     195                 :          0 : s32 txgbe_ee_readw_sw(struct txgbe_hw *hw, u32 offset,
     196                 :            :                               u16 *data)
     197                 :            : {
     198                 :            :         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
     199                 :          0 :         u32 addr = hw->rom.sw_addr + (offset << 1);
     200                 :            :         int err;
     201                 :            : 
     202                 :          0 :         err = hw->mac.acquire_swfw_sync(hw, mask);
     203         [ #  # ]:          0 :         if (err)
     204                 :            :                 return err;
     205                 :            : 
     206                 :          0 :         err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2);
     207                 :            : 
     208                 :          0 :         hw->mac.release_swfw_sync(hw, mask);
     209                 :            : 
     210                 :          0 :         return err;
     211                 :            : }
     212                 :            : 
     213                 :            : /**
     214                 :            :  *  txgbe_ee_read32 - Read EEPROM word using a host interface cmd
     215                 :            :  *  @hw: pointer to hardware structure
     216                 :            :  *  @offset: offset of  word in the EEPROM to read
     217                 :            :  *  @data: word read from the EEPROM
     218                 :            :  *
     219                 :            :  *  Reads a 32 bit word from the EEPROM using the hostif.
     220                 :            :  **/
     221                 :          0 : s32 txgbe_ee_read32(struct txgbe_hw *hw, u32 addr, u32 *data)
     222                 :            : {
     223                 :            :         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
     224                 :            :         int err;
     225                 :            : 
     226                 :          0 :         err = hw->mac.acquire_swfw_sync(hw, mask);
     227         [ #  # ]:          0 :         if (err)
     228                 :            :                 return err;
     229                 :            : 
     230                 :          0 :         err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 4);
     231                 :            : 
     232                 :          0 :         hw->mac.release_swfw_sync(hw, mask);
     233                 :            : 
     234                 :          0 :         return err;
     235                 :            : }
     236                 :            : 
     237                 :            : /**
     238                 :            :  *  txgbe_ee_write - Write EEPROM word using hostif
     239                 :            :  *  @hw: pointer to hardware structure
     240                 :            :  *  @offset: offset of  word in the EEPROM to write
     241                 :            :  *  @data: word write to the EEPROM
     242                 :            :  *
     243                 :            :  *  Write a 16 bit word to the EEPROM using the hostif.
     244                 :            :  **/
     245                 :          0 : s32 txgbe_ee_write16(struct txgbe_hw *hw, u32 offset,
     246                 :            :                                u16 data)
     247                 :            : {
     248                 :            :         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
     249                 :          0 :         u32 addr = (offset << 1);
     250                 :            :         int err;
     251                 :            : 
     252                 :          0 :         err = hw->mac.acquire_swfw_sync(hw, mask);
     253         [ #  # ]:          0 :         if (err)
     254                 :            :                 return err;
     255                 :            : 
     256                 :          0 :         err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
     257                 :            : 
     258                 :          0 :         hw->mac.release_swfw_sync(hw, mask);
     259                 :            : 
     260                 :          0 :         return err;
     261                 :            : }
     262                 :            : 
     263                 :            : /**
     264                 :            :  *  txgbe_ee_writew_buffer - Write EEPROM word(s) using hostif
     265                 :            :  *  @hw: pointer to hardware structure
     266                 :            :  *  @offset: offset of  word in the EEPROM to write
     267                 :            :  *  @words: number of words
     268                 :            :  *  @data: word(s) write to the EEPROM
     269                 :            :  *
     270                 :            :  *  Write a 16 bit word(s) to the EEPROM using the hostif.
     271                 :            :  **/
     272                 :          0 : s32 txgbe_ee_writew_buffer(struct txgbe_hw *hw,
     273                 :            :                                       u32 offset, u32 words, void *data)
     274                 :            : {
     275                 :            :         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
     276                 :          0 :         u32 addr = (offset << 1);
     277                 :          0 :         u32 len = (words << 1);
     278                 :            :         u8 *buf = (u8 *)data;
     279                 :            :         int err;
     280                 :            : 
     281                 :          0 :         err = hw->mac.acquire_swfw_sync(hw, mask);
     282         [ #  # ]:          0 :         if (err)
     283                 :            :                 return err;
     284                 :            : 
     285         [ #  # ]:          0 :         while (len) {
     286                 :          0 :                 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
     287                 :            :                                 ? len : TXGBE_PMMBX_DATA_SIZE);
     288                 :            : 
     289                 :          0 :                 err = txgbe_hic_sr_write(hw, addr, buf, seg);
     290         [ #  # ]:          0 :                 if (err)
     291                 :            :                         break;
     292                 :            : 
     293                 :          0 :                 len -= seg;
     294                 :          0 :                 buf += seg;
     295                 :            :         }
     296                 :            : 
     297                 :          0 :         hw->mac.release_swfw_sync(hw, mask);
     298                 :          0 :         return err;
     299                 :            : }
     300                 :            : 
     301                 :          0 : s32 txgbe_ee_writew_sw(struct txgbe_hw *hw, u32 offset,
     302                 :            :                                u16 data)
     303                 :            : {
     304                 :            :         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
     305                 :          0 :         u32 addr = hw->rom.sw_addr + (offset << 1);
     306                 :            :         int err;
     307                 :            : 
     308                 :          0 :         err = hw->mac.acquire_swfw_sync(hw, mask);
     309         [ #  # ]:          0 :         if (err)
     310                 :            :                 return err;
     311                 :            : 
     312                 :          0 :         err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
     313                 :            : 
     314                 :          0 :         hw->mac.release_swfw_sync(hw, mask);
     315                 :            : 
     316                 :          0 :         return err;
     317                 :            : }
     318                 :            : 
     319                 :            : /**
     320                 :            :  *  txgbe_ee_write32 - Read EEPROM word using a host interface cmd
     321                 :            :  *  @hw: pointer to hardware structure
     322                 :            :  *  @offset: offset of  word in the EEPROM to read
     323                 :            :  *  @data: word read from the EEPROM
     324                 :            :  *
     325                 :            :  *  Reads a 32 bit word from the EEPROM using the hostif.
     326                 :            :  **/
     327                 :          0 : s32 txgbe_ee_write32(struct txgbe_hw *hw, u32 addr, u32 data)
     328                 :            : {
     329                 :            :         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
     330                 :            :         int err;
     331                 :            : 
     332                 :          0 :         err = hw->mac.acquire_swfw_sync(hw, mask);
     333         [ #  # ]:          0 :         if (err)
     334                 :            :                 return err;
     335                 :            : 
     336                 :          0 :         err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 4);
     337                 :            : 
     338                 :          0 :         hw->mac.release_swfw_sync(hw, mask);
     339                 :            : 
     340                 :          0 :         return err;
     341                 :            : }
     342                 :            : 
     343                 :            : /**
     344                 :            :  *  txgbe_calc_eeprom_checksum - Calculates and returns the checksum
     345                 :            :  *  @hw: pointer to hardware structure
     346                 :            :  *
     347                 :            :  *  Returns a negative error code on error, or the 16-bit checksum
     348                 :            :  **/
     349                 :            : #define BUFF_SIZE  64
     350                 :          0 : s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw)
     351                 :            : {
     352                 :          0 :         u16 checksum = 0, read_checksum = 0;
     353                 :            :         int i, j, seg;
     354                 :            :         int err;
     355                 :            :         u16 buffer[BUFF_SIZE];
     356                 :            : 
     357                 :          0 :         err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
     358         [ #  # ]:          0 :         if (err) {
     359                 :          0 :                 DEBUGOUT("EEPROM read failed");
     360                 :          0 :                 return err;
     361                 :            :         }
     362                 :            : 
     363         [ #  # ]:          0 :         for (i = 0; i < TXGBE_EE_CSUM_MAX; i += seg) {
     364                 :            :                 seg = (i + BUFF_SIZE < TXGBE_EE_CSUM_MAX
     365         [ #  # ]:          0 :                        ? BUFF_SIZE : TXGBE_EE_CSUM_MAX - i);
     366                 :          0 :                 err = hw->rom.readw_buffer(hw, i, seg, buffer);
     367         [ #  # ]:          0 :                 if (err)
     368                 :          0 :                         return err;
     369         [ #  # ]:          0 :                 for (j = 0; j < seg; j++)
     370                 :          0 :                         checksum += buffer[j];
     371                 :            :         }
     372                 :            : 
     373                 :          0 :         checksum = (u16)TXGBE_EEPROM_SUM - checksum + read_checksum;
     374                 :            : 
     375                 :          0 :         return (s32)checksum;
     376                 :            : }
     377                 :            : 
     378                 :            : /**
     379                 :            :  *  txgbe_validate_eeprom_checksum - Validate EEPROM checksum
     380                 :            :  *  @hw: pointer to hardware structure
     381                 :            :  *  @checksum_val: calculated checksum
     382                 :            :  *
     383                 :            :  *  Performs checksum calculation and validates the EEPROM checksum.  If the
     384                 :            :  *  caller does not need checksum_val, the value can be NULL.
     385                 :            :  **/
     386                 :          0 : s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw,
     387                 :            :                                            u16 *checksum_val)
     388                 :            : {
     389                 :            :         u16 checksum;
     390                 :          0 :         u16 read_checksum = 0;
     391                 :            :         int err;
     392                 :            : 
     393                 :            :         /* Read the first word from the EEPROM. If this times out or fails, do
     394                 :            :          * not continue or we could be in for a very long wait while every
     395                 :            :          * EEPROM read fails
     396                 :            :          */
     397                 :          0 :         err = hw->rom.read16(hw, 0, &checksum);
     398         [ #  # ]:          0 :         if (err) {
     399                 :          0 :                 DEBUGOUT("EEPROM read failed");
     400                 :          0 :                 return err;
     401                 :            :         }
     402                 :            : 
     403                 :          0 :         err = hw->rom.calc_checksum(hw);
     404         [ #  # ]:          0 :         if (err < 0)
     405                 :            :                 return err;
     406                 :            : 
     407                 :          0 :         checksum = (u16)(err & 0xffff);
     408                 :            : 
     409                 :          0 :         err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
     410         [ #  # ]:          0 :         if (err) {
     411                 :          0 :                 DEBUGOUT("EEPROM read failed");
     412                 :          0 :                 return err;
     413                 :            :         }
     414                 :            : 
     415                 :            :         /* Verify read checksum from EEPROM is the same as
     416                 :            :          * calculated checksum
     417                 :            :          */
     418         [ #  # ]:          0 :         if (read_checksum != checksum) {
     419                 :            :                 err = TXGBE_ERR_EEPROM_CHECKSUM;
     420                 :          0 :                 DEBUGOUT("EEPROM checksum error");
     421                 :            :         }
     422                 :            : 
     423                 :            :         /* If the user cares, return the calculated checksum */
     424         [ #  # ]:          0 :         if (checksum_val)
     425                 :          0 :                 *checksum_val = checksum;
     426                 :            : 
     427                 :            :         return err;
     428                 :            : }
     429                 :            : 
     430                 :            : /**
     431                 :            :  *  txgbe_update_eeprom_checksum - Updates the EEPROM checksum
     432                 :            :  *  @hw: pointer to hardware structure
     433                 :            :  **/
     434                 :          0 : s32 txgbe_update_eeprom_checksum(struct txgbe_hw *hw)
     435                 :            : {
     436                 :            :         s32 status;
     437                 :            :         u16 checksum;
     438                 :            : 
     439                 :            :         /* Read the first word from the EEPROM. If this times out or fails, do
     440                 :            :          * not continue or we could be in for a very long wait while every
     441                 :            :          * EEPROM read fails
     442                 :            :          */
     443                 :          0 :         status = hw->rom.read16(hw, 0, &checksum);
     444         [ #  # ]:          0 :         if (status) {
     445                 :          0 :                 DEBUGOUT("EEPROM read failed");
     446                 :          0 :                 return status;
     447                 :            :         }
     448                 :            : 
     449                 :          0 :         status = hw->rom.calc_checksum(hw);
     450         [ #  # ]:          0 :         if (status < 0)
     451                 :            :                 return status;
     452                 :            : 
     453                 :          0 :         checksum = (u16)(status & 0xffff);
     454                 :            : 
     455                 :          0 :         status = hw->rom.writew_sw(hw, TXGBE_EEPROM_CHECKSUM, checksum);
     456                 :            : 
     457                 :          0 :         return status;
     458                 :            : }
     459                 :            : 

Generated by: LCOV version 1.14