LCOV - code coverage report
Current view: top level - drivers/net/ixgbe - ixgbe_bypass_api.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 83 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 4 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 39 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2010-2014 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #ifndef _IXGBE_BYPASS_API_H_
       6                 :            : #define _IXGBE_BYPASS_API_H_
       7                 :            : 
       8                 :            : #ifdef RTE_LIBRTE_IXGBE_BYPASS
       9                 :            : 
      10                 :            : #include "ixgbe_bypass_defines.h"
      11                 :            : /**
      12                 :            :  *  ixgbe_bypass_rw_generic - Bit bang data into by_pass FW
      13                 :            :  *
      14                 :            :  *  @hw: pointer to hardware structure
      15                 :            :  *  @cmd: Command we send to the FW
      16                 :            :  *  @status: The reply from the FW
      17                 :            :  *
      18                 :            :  *  Bit-bangs the cmd to the by_pass FW status points to what is returned.
      19                 :            :  **/
      20                 :            : #define IXGBE_BYPASS_BB_WAIT 1
      21                 :          0 : static s32 ixgbe_bypass_rw_generic(struct ixgbe_hw *hw, u32 cmd, u32 *status)
      22                 :            : {
      23                 :            :         int i;
      24                 :            :         u32 sck, sdi, sdo, dir_sck, dir_sdi, dir_sdo;
      25                 :            :         u32 esdp;
      26                 :            : 
      27         [ #  # ]:          0 :         if (!status)
      28                 :            :                 return IXGBE_ERR_PARAM;
      29                 :            : 
      30                 :          0 :         *status = 0;
      31                 :            : 
      32                 :            :         /* SDP vary by MAC type */
      33   [ #  #  #  # ]:          0 :         switch (hw->mac.type) {
      34                 :            :         case ixgbe_mac_82599EB:
      35                 :            :                 sck = IXGBE_ESDP_SDP7;
      36                 :            :                 sdi = IXGBE_ESDP_SDP0;
      37                 :            :                 sdo = IXGBE_ESDP_SDP6;
      38                 :            :                 dir_sck = IXGBE_ESDP_SDP7_DIR;
      39                 :            :                 dir_sdi = IXGBE_ESDP_SDP0_DIR;
      40                 :            :                 dir_sdo = IXGBE_ESDP_SDP6_DIR;
      41                 :            :                 break;
      42                 :          0 :         case ixgbe_mac_X540:
      43                 :            :                 sck = IXGBE_ESDP_SDP2;
      44                 :            :                 sdi = IXGBE_ESDP_SDP0;
      45                 :            :                 sdo = IXGBE_ESDP_SDP1;
      46                 :            :                 dir_sck = IXGBE_ESDP_SDP2_DIR;
      47                 :            :                 dir_sdi = IXGBE_ESDP_SDP0_DIR;
      48                 :            :                 dir_sdo = IXGBE_ESDP_SDP1_DIR;
      49                 :          0 :                 break;
      50                 :          0 :         case ixgbe_mac_X550:
      51                 :            :         case ixgbe_mac_X550EM_x:
      52                 :            :         case ixgbe_mac_X550EM_a:
      53                 :            :                 sck = IXGBE_ESDP_SDP2;
      54                 :            :                 sdi = IXGBE_ESDP_SDP0;
      55                 :            :                 sdo = IXGBE_ESDP_SDP1;
      56                 :            :                 dir_sck = IXGBE_ESDP_SDP2_DIR;
      57                 :            :                 dir_sdi = IXGBE_ESDP_SDP0_DIR;
      58                 :            :                 dir_sdo = IXGBE_ESDP_SDP1_DIR;
      59                 :          0 :                 break;
      60                 :            :         default:
      61                 :            :                 return IXGBE_ERR_DEVICE_NOT_SUPPORTED;
      62                 :            :         }
      63                 :            : 
      64                 :            :         /* Set SDP pins direction */
      65                 :          0 :         esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
      66                 :          0 :         esdp |= dir_sck;        /* SCK as output */
      67                 :          0 :         esdp |= dir_sdi;        /* SDI as output */
      68                 :          0 :         esdp &= ~dir_sdo;   /* SDO as input */
      69                 :          0 :         esdp |= sck;
      70                 :          0 :         esdp |= sdi;
      71                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
      72                 :          0 :         IXGBE_WRITE_FLUSH(hw);
      73                 :            :   //  TODO:
      74                 :          0 :         msleep(IXGBE_BYPASS_BB_WAIT);
      75                 :            : 
      76                 :            :         /* Generate start condition */
      77                 :            :         esdp &= ~sdi;
      78                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
      79                 :          0 :         IXGBE_WRITE_FLUSH(hw);
      80                 :          0 :         msleep(IXGBE_BYPASS_BB_WAIT);
      81                 :            : 
      82                 :          0 :         esdp &= ~sck;
      83                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
      84                 :          0 :         IXGBE_WRITE_FLUSH(hw);
      85                 :          0 :         msleep(IXGBE_BYPASS_BB_WAIT);
      86                 :            : 
      87                 :            :         /* Clock out the new control word and clock in the status */
      88         [ #  # ]:          0 :         for (i = 0; i < 32; i++) {
      89         [ #  # ]:          0 :                 if ((cmd >> (31 - i)) & 0x01) {
      90                 :          0 :                         esdp |= sdi;
      91                 :          0 :                         IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
      92                 :            :                 } else {
      93                 :          0 :                         esdp &= ~sdi;
      94                 :          0 :                         IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
      95                 :            :                 }
      96                 :          0 :                 IXGBE_WRITE_FLUSH(hw);
      97                 :          0 :                 msleep(IXGBE_BYPASS_BB_WAIT);
      98                 :            : 
      99                 :          0 :                 esdp |= sck;
     100                 :          0 :                 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
     101                 :          0 :                 IXGBE_WRITE_FLUSH(hw);
     102                 :          0 :                 msleep(IXGBE_BYPASS_BB_WAIT);
     103                 :            : 
     104                 :          0 :                 esdp &= ~sck;
     105                 :          0 :                 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
     106                 :          0 :                 IXGBE_WRITE_FLUSH(hw);
     107                 :          0 :                 msleep(IXGBE_BYPASS_BB_WAIT);
     108                 :            : 
     109                 :          0 :                 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
     110         [ #  # ]:          0 :                 if (esdp & sdo)
     111                 :          0 :                         *status = (*status << 1) | 0x01;
     112                 :            :                 else
     113                 :          0 :                         *status = (*status << 1) | 0x00;
     114                 :          0 :                 msleep(IXGBE_BYPASS_BB_WAIT);
     115                 :            :         }
     116                 :            : 
     117                 :            :         /* stop condition */
     118                 :          0 :         esdp |= sck;
     119                 :          0 :         esdp &= ~sdi;
     120                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
     121                 :          0 :         IXGBE_WRITE_FLUSH(hw);
     122                 :          0 :         msleep(IXGBE_BYPASS_BB_WAIT);
     123                 :            : 
     124                 :          0 :         esdp |= sdi;
     125                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
     126                 :          0 :         IXGBE_WRITE_FLUSH(hw);
     127                 :            : 
     128                 :            :         /* set the page bits to match the cmd that the status it belongs to */
     129                 :          0 :         *status = (*status & 0x3fffffff) | (cmd & 0xc0000000);
     130                 :            : 
     131                 :          0 :         return 0;
     132                 :            : }
     133                 :            : 
     134                 :            : /**
     135                 :            :  * ixgbe_bypass_valid_rd_generic - Verify valid return from bit-bang.
     136                 :            :  *
     137                 :            :  * If we send a write we can't be sure it took until we can read back
     138                 :            :  * that same register.  It can be a problem as some of the fields may
     139                 :            :  * for valid reasons change between the time wrote the register and
     140                 :            :  * we read it again to verify.  So this function check everything we
     141                 :            :  * can check and then assumes it worked.
     142                 :            :  *
     143                 :            :  * @u32 in_reg - The register cmd for the bit-bang read.
     144                 :            :  * @u32 out_reg - The register returned from a bit-bang read.
     145                 :            :  **/
     146                 :          0 : static bool ixgbe_bypass_valid_rd_generic(u32 in_reg, u32 out_reg)
     147                 :            : {
     148                 :            :         u32 mask;
     149                 :            : 
     150                 :            :         /* Page must match for all control pages */
     151         [ #  # ]:          0 :         if ((in_reg & BYPASS_PAGE_M) != (out_reg & BYPASS_PAGE_M))
     152                 :            :                 return false;
     153                 :            : 
     154      [ #  #  # ]:          0 :         switch (in_reg & BYPASS_PAGE_M) {
     155                 :          0 :         case BYPASS_PAGE_CTL0:
     156                 :            :                 /* All the following can't change since the last write
     157                 :            :                  *  - All the event actions
     158                 :            :                  *  - The timeout value
     159                 :            :                  */
     160                 :            :                 mask = BYPASS_AUX_ON_M | BYPASS_MAIN_ON_M |
     161                 :            :                        BYPASS_MAIN_OFF_M | BYPASS_AUX_OFF_M |
     162                 :            :                        BYPASS_WDTIMEOUT_M |
     163                 :            :                        BYPASS_WDT_VALUE_M;
     164         [ #  # ]:          0 :                 if ((out_reg & mask) != (in_reg & mask))
     165                 :            :                         return false;
     166                 :            : 
     167                 :            :                 /* 0x0 is never a valid value for bypass status */
     168         [ #  # ]:          0 :                 if (!(out_reg & BYPASS_STATUS_OFF_M))
     169                 :          0 :                         return false;
     170                 :            :                 break;
     171                 :          0 :         case BYPASS_PAGE_CTL1:
     172                 :            :                 /* All the following can't change since the last write
     173                 :            :                  *  - time valid bit
     174                 :            :                  *  - time we last sent
     175                 :            :                  */
     176                 :            :                 mask = BYPASS_CTL1_VALID_M | BYPASS_CTL1_TIME_M;
     177         [ #  # ]:          0 :                 if ((out_reg & mask) != (in_reg & mask))
     178                 :          0 :                         return false;
     179                 :            :                 break;
     180                 :            :         case BYPASS_PAGE_CTL2:
     181                 :            :                 /* All we can check in this page is control number
     182                 :            :                  * which is already done above.
     183                 :            :                  */
     184                 :            :                 break;
     185                 :            :         }
     186                 :            : 
     187                 :            :         /* We are as sure as we can be return true */
     188                 :            :         return true;
     189                 :            : }
     190                 :            : 
     191                 :            : /**
     192                 :            :  *  ixgbe_bypass_set_generic - Set a bypass field in the FW CTRL Register.
     193                 :            :  *
     194                 :            :  *  @hw: pointer to hardware structure
     195                 :            :  *  @cmd: The control word we are setting.
     196                 :            :  *  @event: The event we are setting in the FW.  This also happens to
     197                 :            :  *          be the mask for the event we are setting (handy)
     198                 :            :  *  @action: The action we set the event to in the FW. This is in a
     199                 :            :  *           bit field that happens to be what we want to put in
     200                 :            :  *           the event spot (also handy)
     201                 :            :  **/
     202                 :          0 : static s32 ixgbe_bypass_set_generic(struct ixgbe_hw *hw, u32 ctrl, u32 event,
     203                 :            :                              u32 action)
     204                 :            : {
     205                 :          0 :         u32 by_ctl = 0;
     206                 :            :         u32 cmd, verify;
     207                 :            :         u32 count = 0;
     208                 :            : 
     209                 :            :         /* Get current values */
     210                 :            :         cmd = ctrl;     /* just reading only need control number */
     211         [ #  # ]:          0 :         if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
     212                 :            :                 return IXGBE_ERR_INVALID_ARGUMENT;
     213                 :            : 
     214                 :            :         /* Set to new action */
     215                 :          0 :         cmd = (by_ctl & ~event) | BYPASS_WE | action;
     216         [ #  # ]:          0 :         if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
     217                 :            :                 return IXGBE_ERR_INVALID_ARGUMENT;
     218                 :            : 
     219                 :            :         /* Page 0 force a FW eeprom write which is slow so verify */
     220         [ #  # ]:          0 :         if ((cmd & BYPASS_PAGE_M) == BYPASS_PAGE_CTL0) {
     221                 :            :                 verify = BYPASS_PAGE_CTL0;
     222                 :            :                 do {
     223         [ #  # ]:          0 :                         if (count++ > 5)
     224                 :            :                                 return IXGBE_BYPASS_FW_WRITE_FAILURE;
     225                 :            : 
     226         [ #  # ]:          0 :                         if (ixgbe_bypass_rw_generic(hw, verify, &by_ctl))
     227                 :            :                                 return IXGBE_ERR_INVALID_ARGUMENT;
     228         [ #  # ]:          0 :                 } while (!ixgbe_bypass_valid_rd_generic(cmd, by_ctl));
     229                 :            :         } else {
     230                 :            :                 /* We have give the FW time for the write to stick */
     231                 :          0 :                 msleep(100);
     232                 :            :         }
     233                 :            : 
     234                 :            :         return 0;
     235                 :            : }
     236                 :            : 
     237                 :            : /**
     238                 :            :  *  ixgbe_bypass_rd_eep_generic - Read the bypass FW eeprom address.
     239                 :            :  *
     240                 :            :  *  @hw: pointer to hardware structure
     241                 :            :  *  @addr: The bypass eeprom address to read.
     242                 :            :  *  @value: The 8b of data at the address above.
     243                 :            :  **/
     244                 :          0 : static s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value)
     245                 :            : {
     246                 :            :         u32 cmd;
     247                 :            :         u32 status;
     248                 :            : 
     249                 :            : 
     250                 :            :         /* send the request */
     251                 :            :         cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
     252                 :          0 :         cmd |= (addr << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
     253         [ #  # ]:          0 :         if (ixgbe_bypass_rw_generic(hw, cmd, &status))
     254                 :            :                 return IXGBE_ERR_INVALID_ARGUMENT;
     255                 :            : 
     256                 :            :         /* We have give the FW time for the write to stick */
     257                 :          0 :         msleep(100);
     258                 :            : 
     259                 :            :         /* now read the results */
     260                 :          0 :         cmd &= ~BYPASS_WE;
     261         [ #  # ]:          0 :         if (ixgbe_bypass_rw_generic(hw, cmd, &status))
     262                 :            :                 return IXGBE_ERR_INVALID_ARGUMENT;
     263                 :            : 
     264                 :          0 :         *value = status & BYPASS_CTL2_DATA_M;
     265                 :            : 
     266                 :          0 :         return 0;
     267                 :            : }
     268                 :            : 
     269                 :            : #endif /* RTE_LIBRTE_IXGBE_BYPASS */
     270                 :            : 
     271                 :            : #endif /* _IXGBE_BYPASS_API_H_ */

Generated by: LCOV version 1.14