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

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2001-2024 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "ixgbe_type.h"
       6                 :            : #include "ixgbe_mbx.h"
       7                 :            : 
       8                 :            : STATIC s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id);
       9                 :            : STATIC s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id);
      10                 :            : 
      11                 :            : /**
      12                 :            :  * ixgbe_read_mbx - Reads a message from the mailbox
      13                 :            :  * @hw: pointer to the HW structure
      14                 :            :  * @msg: The message buffer
      15                 :            :  * @size: Length of buffer
      16                 :            :  * @mbx_id: id of mailbox to read
      17                 :            :  *
      18                 :            :  * returns SUCCESS if it successfully read message from buffer
      19                 :            :  **/
      20                 :          0 : s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
      21                 :            : {
      22                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
      23                 :            : 
      24                 :          0 :         DEBUGFUNC("ixgbe_read_mbx");
      25                 :            : 
      26                 :            :         /* limit read to size of mailbox */
      27         [ #  # ]:          0 :         if (size > mbx->size) {
      28                 :          0 :                 ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
      29                 :            :                               "Invalid mailbox message size %u, changing to %u",
      30                 :            :                               size, mbx->size);
      31                 :          0 :                 size = mbx->size;
      32                 :            :         }
      33                 :            : 
      34         [ #  # ]:          0 :         if (mbx->ops[mbx_id].read)
      35                 :          0 :                 return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
      36                 :            : 
      37                 :            :         return IXGBE_ERR_CONFIG;
      38                 :            : }
      39                 :            : 
      40                 :            : /**
      41                 :            :  * ixgbe_poll_mbx - Wait for message and read it from the mailbox
      42                 :            :  * @hw: pointer to the HW structure
      43                 :            :  * @msg: The message buffer
      44                 :            :  * @size: Length of buffer
      45                 :            :  * @mbx_id: id of mailbox to read
      46                 :            :  *
      47                 :            :  * returns SUCCESS if it successfully read message from buffer
      48                 :            :  **/
      49                 :          0 : s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
      50                 :            : {
      51                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
      52                 :            :         s32 ret_val;
      53                 :            : 
      54                 :          0 :         DEBUGFUNC("ixgbe_poll_mbx");
      55                 :            : 
      56   [ #  #  #  # ]:          0 :         if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg ||
      57         [ #  # ]:          0 :             !mbx->timeout)
      58                 :            :                 return IXGBE_ERR_CONFIG;
      59                 :            : 
      60                 :            :         /* limit read to size of mailbox */
      61         [ #  # ]:          0 :         if (size > mbx->size) {
      62                 :          0 :                 ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
      63                 :            :                               "Invalid mailbox message size %u, changing to %u",
      64                 :            :                               size, mbx->size);
      65                 :          0 :                 size = mbx->size;
      66                 :            :         }
      67                 :            : 
      68                 :          0 :         ret_val = ixgbe_poll_for_msg(hw, mbx_id);
      69                 :            :         /* if ack received read message, otherwise we timed out */
      70         [ #  # ]:          0 :         if (!ret_val)
      71                 :          0 :                 return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
      72                 :            : 
      73                 :            :         return ret_val;
      74                 :            : }
      75                 :            : 
      76                 :            : /**
      77                 :            :  * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK
      78                 :            :  * @hw: pointer to the HW structure
      79                 :            :  * @msg: The message buffer
      80                 :            :  * @size: Length of buffer
      81                 :            :  * @mbx_id: id of mailbox to write
      82                 :            :  *
      83                 :            :  * returns SUCCESS if it successfully copied message into the buffer and
      84                 :            :  * received an ACK to that message within specified period
      85                 :            :  *
      86                 :            :  * Note that the caller to this function must lock before calling, since
      87                 :            :  * multiple threads can destroy each other messages.
      88                 :            :  **/
      89                 :          0 : s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
      90                 :            : {
      91                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
      92                 :            :         s32 ret_val = IXGBE_ERR_MBX;
      93                 :            : 
      94                 :          0 :         DEBUGFUNC("ixgbe_write_mbx");
      95                 :            : 
      96                 :            :         /*
      97                 :            :          * exit if either we can't write, release
      98                 :            :          * or there is no timeout defined
      99                 :            :          */
     100   [ #  #  #  # ]:          0 :         if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack ||
     101   [ #  #  #  # ]:          0 :             !mbx->ops[mbx_id].release || !mbx->timeout)
     102                 :            :                 return IXGBE_ERR_CONFIG;
     103                 :            : 
     104         [ #  # ]:          0 :         if (size > mbx->size) {
     105                 :            :                 ret_val = IXGBE_ERR_PARAM;
     106                 :          0 :                 ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
     107                 :            :                              "Invalid mailbox message size %u", size);
     108                 :            :         } else {
     109                 :          0 :                 ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id);
     110                 :            :         }
     111                 :            : 
     112                 :            :         return ret_val;
     113                 :            : }
     114                 :            : 
     115                 :            : /**
     116                 :            :  * ixgbe_check_for_msg - checks to see if someone sent us mail
     117                 :            :  * @hw: pointer to the HW structure
     118                 :            :  * @mbx_id: id of mailbox to check
     119                 :            :  *
     120                 :            :  * returns SUCCESS if the Status bit was found or else ERR_MBX
     121                 :            :  **/
     122                 :          0 : s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
     123                 :            : {
     124                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     125                 :            :         s32 ret_val = IXGBE_ERR_CONFIG;
     126                 :            : 
     127                 :          0 :         DEBUGFUNC("ixgbe_check_for_msg");
     128                 :            : 
     129         [ #  # ]:          0 :         if (mbx->ops[mbx_id].check_for_msg)
     130                 :          0 :                 ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id);
     131                 :            : 
     132                 :          0 :         return ret_val;
     133                 :            : }
     134                 :            : 
     135                 :            : /**
     136                 :            :  * ixgbe_check_for_ack - checks to see if someone sent us ACK
     137                 :            :  * @hw: pointer to the HW structure
     138                 :            :  * @mbx_id: id of mailbox to check
     139                 :            :  *
     140                 :            :  * returns SUCCESS if the Status bit was found or else ERR_MBX
     141                 :            :  **/
     142                 :          0 : s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
     143                 :            : {
     144                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     145                 :            :         s32 ret_val = IXGBE_ERR_CONFIG;
     146                 :            : 
     147                 :          0 :         DEBUGFUNC("ixgbe_check_for_ack");
     148                 :            : 
     149         [ #  # ]:          0 :         if (mbx->ops[mbx_id].check_for_ack)
     150                 :          0 :                 ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id);
     151                 :            : 
     152                 :          0 :         return ret_val;
     153                 :            : }
     154                 :            : 
     155                 :            : /**
     156                 :            :  * ixgbe_check_for_rst - checks to see if other side has reset
     157                 :            :  * @hw: pointer to the HW structure
     158                 :            :  * @mbx_id: id of mailbox to check
     159                 :            :  *
     160                 :            :  * returns SUCCESS if the Status bit was found or else ERR_MBX
     161                 :            :  **/
     162                 :          0 : s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
     163                 :            : {
     164                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     165                 :            :         s32 ret_val = IXGBE_ERR_CONFIG;
     166                 :            : 
     167                 :          0 :         DEBUGFUNC("ixgbe_check_for_rst");
     168                 :            : 
     169         [ #  # ]:          0 :         if (mbx->ops[mbx_id].check_for_rst)
     170                 :          0 :                 ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id);
     171                 :            : 
     172                 :          0 :         return ret_val;
     173                 :            : }
     174                 :            : 
     175                 :            : /**
     176                 :            :  * ixgbe_clear_mbx - Clear Mailbox Memory
     177                 :            :  * @hw: pointer to the HW structure
     178                 :            :  * @mbx_id: id of mailbox to write
     179                 :            :  *
     180                 :            :  * Set VFMBMEM of given VF to 0x0.
     181                 :            :  **/
     182                 :          0 : s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 mbx_id)
     183                 :            : {
     184                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     185                 :            :         s32 ret_val = IXGBE_ERR_CONFIG;
     186                 :            : 
     187                 :          0 :         DEBUGFUNC("ixgbe_clear_mbx");
     188                 :            : 
     189         [ #  # ]:          0 :         if (mbx->ops[mbx_id].clear)
     190                 :          0 :                 ret_val = mbx->ops[mbx_id].clear(hw, mbx_id);
     191                 :            : 
     192                 :          0 :         return ret_val;
     193                 :            : }
     194                 :            : 
     195                 :            : /**
     196                 :            :  * ixgbe_poll_for_msg - Wait for message notification
     197                 :            :  * @hw: pointer to the HW structure
     198                 :            :  * @mbx_id: id of mailbox to write
     199                 :            :  *
     200                 :            :  * returns SUCCESS if it successfully received a message notification
     201                 :            :  **/
     202                 :          0 : STATIC s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
     203                 :            : {
     204                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     205                 :          0 :         int countdown = mbx->timeout;
     206                 :            : 
     207                 :          0 :         DEBUGFUNC("ixgbe_poll_for_msg");
     208                 :            : 
     209   [ #  #  #  # ]:          0 :         if (!countdown || !mbx->ops[mbx_id].check_for_msg)
     210                 :            :                 return IXGBE_ERR_CONFIG;
     211                 :            : 
     212         [ #  # ]:          0 :         while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) {
     213                 :          0 :                 countdown--;
     214         [ #  # ]:          0 :                 if (!countdown)
     215                 :            :                         break;
     216                 :          0 :                 usec_delay(mbx->usec_delay);
     217                 :            :         }
     218                 :            : 
     219         [ #  # ]:          0 :         if (countdown == 0) {
     220                 :          0 :                 ERROR_REPORT2(IXGBE_ERROR_POLLING,
     221                 :            :                            "Polling for VF%u mailbox message timedout", mbx_id);
     222                 :          0 :                 return IXGBE_ERR_TIMEOUT;
     223                 :            :         }
     224                 :            : 
     225                 :            :         return IXGBE_SUCCESS;
     226                 :            : }
     227                 :            : 
     228                 :            : /**
     229                 :            :  * ixgbe_poll_for_ack - Wait for message acknowledgment
     230                 :            :  * @hw: pointer to the HW structure
     231                 :            :  * @mbx_id: id of mailbox to write
     232                 :            :  *
     233                 :            :  * returns SUCCESS if it successfully received a message acknowledgment
     234                 :            :  **/
     235                 :          0 : STATIC s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
     236                 :            : {
     237                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     238                 :          0 :         int countdown = mbx->timeout;
     239                 :            : 
     240                 :          0 :         DEBUGFUNC("ixgbe_poll_for_ack");
     241                 :            : 
     242   [ #  #  #  # ]:          0 :         if (!countdown || !mbx->ops[mbx_id].check_for_ack)
     243                 :            :                 return IXGBE_ERR_CONFIG;
     244                 :            : 
     245         [ #  # ]:          0 :         while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) {
     246                 :          0 :                 countdown--;
     247         [ #  # ]:          0 :                 if (!countdown)
     248                 :            :                         break;
     249                 :          0 :                 usec_delay(mbx->usec_delay);
     250                 :            :         }
     251                 :            : 
     252         [ #  # ]:          0 :         if (countdown == 0) {
     253                 :          0 :                 ERROR_REPORT2(IXGBE_ERROR_POLLING,
     254                 :            :                              "Polling for VF%u mailbox ack timedout", mbx_id);
     255                 :          0 :                 return IXGBE_ERR_TIMEOUT;
     256                 :            :         }
     257                 :            : 
     258                 :            :         return IXGBE_SUCCESS;
     259                 :            : }
     260                 :            : 
     261                 :            : /**
     262                 :            :  * ixgbe_read_mailbox_vf - read VF's mailbox register
     263                 :            :  * @hw: pointer to the HW structure
     264                 :            :  *
     265                 :            :  * This function is used to read the mailbox register dedicated for VF without
     266                 :            :  * losing the read to clear status bits.
     267                 :            :  **/
     268                 :            : STATIC u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw)
     269                 :            : {
     270                 :          0 :         u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
     271                 :            : 
     272                 :          0 :         vf_mailbox |= hw->mbx.vf_mailbox;
     273                 :          0 :         hw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
     274                 :            : 
     275                 :            :         return vf_mailbox;
     276                 :            : }
     277                 :            : 
     278                 :            : STATIC void ixgbe_clear_msg_vf(struct ixgbe_hw *hw)
     279                 :            : {
     280                 :            :         u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
     281                 :            : 
     282   [ #  #  #  #  :          0 :         if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {
                   #  # ]
     283                 :          0 :                 hw->mbx.stats.reqs++;
     284                 :          0 :                 hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;
     285                 :            :         }
     286                 :            : }
     287                 :            : 
     288                 :            : STATIC void ixgbe_clear_ack_vf(struct ixgbe_hw *hw)
     289                 :            : {
     290                 :            :         u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
     291                 :            : 
     292   [ #  #  #  #  :          0 :         if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {
                   #  # ]
     293                 :          0 :                 hw->mbx.stats.acks++;
     294                 :          0 :                 hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;
     295                 :            :         }
     296                 :            : }
     297                 :            : 
     298                 :            : STATIC void ixgbe_clear_rst_vf(struct ixgbe_hw *hw)
     299                 :            : {
     300                 :            :         u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
     301                 :            : 
     302         [ #  # ]:          0 :         if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {
     303                 :          0 :                 hw->mbx.stats.rsts++;
     304                 :          0 :                 hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |
     305                 :            :                                         IXGBE_VFMAILBOX_RSTD);
     306                 :            :         }
     307                 :            : }
     308                 :            : 
     309                 :            : /**
     310                 :            :  * ixgbe_check_for_bit_vf - Determine if a status bit was set
     311                 :            :  * @hw: pointer to the HW structure
     312                 :            :  * @mask: bitmask for bits to be tested and cleared
     313                 :            :  *
     314                 :            :  * This function is used to check for the read to clear bits within
     315                 :            :  * the V2P mailbox.
     316                 :            :  **/
     317                 :            : STATIC s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
     318                 :            : {
     319                 :            :         u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
     320                 :            : 
     321   [ #  #  #  #  :          0 :         if (vf_mailbox & mask)
                   #  # ]
     322                 :            :                 return IXGBE_SUCCESS;
     323                 :            : 
     324                 :            :         return IXGBE_ERR_MBX;
     325                 :            : }
     326                 :            : 
     327                 :            : /**
     328                 :            :  * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
     329                 :            :  * @hw: pointer to the HW structure
     330                 :            :  * @mbx_id: id of mailbox to check
     331                 :            :  *
     332                 :            :  * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
     333                 :            :  **/
     334                 :          0 : STATIC s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
     335                 :            : {
     336                 :            :         UNREFERENCED_1PARAMETER(mbx_id);
     337                 :          0 :         DEBUGFUNC("ixgbe_check_for_msg_vf");
     338                 :            : 
     339                 :            :         if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS))
     340                 :          0 :                 return IXGBE_SUCCESS;
     341                 :            : 
     342                 :            :         return IXGBE_ERR_MBX;
     343                 :            : }
     344                 :            : 
     345                 :            : /**
     346                 :            :  * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
     347                 :            :  * @hw: pointer to the HW structure
     348                 :            :  * @mbx_id: id of mailbox to check
     349                 :            :  *
     350                 :            :  * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
     351                 :            :  **/
     352                 :          0 : STATIC s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
     353                 :            : {
     354                 :            :         UNREFERENCED_1PARAMETER(mbx_id);
     355                 :          0 :         DEBUGFUNC("ixgbe_check_for_ack_vf");
     356                 :            : 
     357                 :            :         if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
     358                 :            :                 /* TODO: should this be autocleared? */
     359                 :            :                 ixgbe_clear_ack_vf(hw);
     360                 :          0 :                 return IXGBE_SUCCESS;
     361                 :            :         }
     362                 :            : 
     363                 :            :         return IXGBE_ERR_MBX;
     364                 :            : }
     365                 :            : 
     366                 :            : /**
     367                 :            :  * ixgbe_check_for_rst_vf - checks to see if the PF has reset
     368                 :            :  * @hw: pointer to the HW structure
     369                 :            :  * @mbx_id: id of mailbox to check
     370                 :            :  *
     371                 :            :  * returns true if the PF has set the reset done bit or else false
     372                 :            :  **/
     373                 :          0 : STATIC s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
     374                 :            : {
     375                 :            :         UNREFERENCED_1PARAMETER(mbx_id);
     376                 :          0 :         DEBUGFUNC("ixgbe_check_for_rst_vf");
     377                 :            : 
     378                 :            :         if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI |
     379                 :            :                                           IXGBE_VFMAILBOX_RSTD)) {
     380                 :            :                 /* TODO: should this be autocleared? */
     381                 :            :                 ixgbe_clear_rst_vf(hw);
     382                 :          0 :                 return IXGBE_SUCCESS;
     383                 :            :         }
     384                 :            : 
     385                 :            :         return IXGBE_ERR_MBX;
     386                 :            : }
     387                 :            : 
     388                 :            : /**
     389                 :            :  * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
     390                 :            :  * @hw: pointer to the HW structure
     391                 :            :  *
     392                 :            :  * return SUCCESS if we obtained the mailbox lock
     393                 :            :  **/
     394                 :          0 : STATIC s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
     395                 :            : {
     396                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     397                 :          0 :         int countdown = mbx->timeout;
     398                 :            :         s32 ret_val = IXGBE_ERR_MBX;
     399                 :            :         u32 vf_mailbox;
     400                 :            : 
     401                 :          0 :         DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
     402                 :            : 
     403         [ #  # ]:          0 :         if (!mbx->timeout)
     404                 :            :                 return IXGBE_ERR_CONFIG;
     405                 :            : 
     406         [ #  # ]:          0 :         while (countdown--) {
     407                 :            :                 /* Reserve mailbox for VF use */
     408                 :            :                 vf_mailbox = ixgbe_read_mailbox_vf(hw);
     409                 :          0 :                 vf_mailbox |= IXGBE_VFMAILBOX_VFU;
     410                 :          0 :                 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
     411                 :            : 
     412                 :            :                 /* Verify that VF is the owner of the lock */
     413         [ #  # ]:          0 :                 if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {
     414                 :            :                         ret_val = IXGBE_SUCCESS;
     415                 :            :                         break;
     416                 :            :                 }
     417                 :            : 
     418                 :            :                 /* Wait a bit before trying again */
     419                 :          0 :                 usec_delay(mbx->usec_delay);
     420                 :            :         }
     421                 :            : 
     422         [ #  # ]:          0 :         if (ret_val != IXGBE_SUCCESS) {
     423                 :          0 :                 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
     424                 :            :                                 "Failed to obtain mailbox lock");
     425                 :            :                 ret_val = IXGBE_ERR_TIMEOUT;
     426                 :            :         }
     427                 :            : 
     428                 :            :         return ret_val;
     429                 :            : }
     430                 :            : 
     431                 :            : /**
     432                 :            :  * ixgbe_release_mbx_lock_dummy - release mailbox lock
     433                 :            :  * @hw: pointer to the HW structure
     434                 :            :  * @mbx_id: id of mailbox to read
     435                 :            :  **/
     436                 :          0 : STATIC void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id)
     437                 :            : {
     438                 :            :         UNREFERENCED_2PARAMETER(hw, mbx_id);
     439                 :            : 
     440                 :          0 :         DEBUGFUNC("ixgbe_release_mbx_lock_dummy");
     441                 :          0 : }
     442                 :            : 
     443                 :            : /**
     444                 :            :  * ixgbe_release_mbx_lock_vf - release mailbox lock
     445                 :            :  * @hw: pointer to the HW structure
     446                 :            :  * @mbx_id: id of mailbox to read
     447                 :            :  **/
     448                 :          0 : STATIC void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id)
     449                 :            : {
     450                 :            :         u32 vf_mailbox;
     451                 :            : 
     452                 :            :         UNREFERENCED_1PARAMETER(mbx_id);
     453                 :            : 
     454                 :          0 :         DEBUGFUNC("ixgbe_release_mbx_lock_vf");
     455                 :            : 
     456                 :            :         /* Return ownership of the buffer */
     457                 :            :         vf_mailbox = ixgbe_read_mailbox_vf(hw);
     458                 :          0 :         vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;
     459                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
     460                 :          0 : }
     461                 :            : 
     462                 :            : /**
     463                 :            :  * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox
     464                 :            :  * @hw: pointer to the HW structure
     465                 :            :  * @msg: The message buffer
     466                 :            :  * @size: Length of buffer
     467                 :            :  * @mbx_id: id of mailbox to write
     468                 :            :  *
     469                 :            :  * returns SUCCESS if it successfully copied message into the buffer
     470                 :            :  **/
     471                 :          0 : STATIC s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
     472                 :            :                                      u16 mbx_id)
     473                 :            : {
     474                 :            :         s32 ret_val;
     475                 :            :         u16 i;
     476                 :            : 
     477                 :            :         UNREFERENCED_1PARAMETER(mbx_id);
     478                 :          0 :         DEBUGFUNC("ixgbe_write_mbx_vf_legacy");
     479                 :            : 
     480                 :            :         /* lock the mailbox to prevent pf/vf race condition */
     481                 :          0 :         ret_val = ixgbe_obtain_mbx_lock_vf(hw);
     482         [ #  # ]:          0 :         if (ret_val)
     483                 :            :                 return ret_val;
     484                 :            : 
     485                 :            :         /* flush msg and acks as we are overwriting the message buffer */
     486                 :          0 :         ixgbe_check_for_msg_vf(hw, 0);
     487                 :            :         ixgbe_clear_msg_vf(hw);
     488                 :          0 :         ixgbe_check_for_ack_vf(hw, 0);
     489                 :            :         ixgbe_clear_ack_vf(hw);
     490                 :            : 
     491                 :            :         /* copy the caller specified message to the mailbox memory buffer */
     492         [ #  # ]:          0 :         for (i = 0; i < size; i++)
     493                 :          0 :                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
     494                 :            : 
     495                 :            :         /* update stats */
     496                 :          0 :         hw->mbx.stats.msgs_tx++;
     497                 :            : 
     498                 :            :         /* interrupt the PF to tell it a message has been sent */
     499                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
     500                 :            : 
     501                 :          0 :         return IXGBE_SUCCESS;
     502                 :            : }
     503                 :            : 
     504                 :            : /**
     505                 :            :  * ixgbe_write_mbx_vf - Write a message to the mailbox
     506                 :            :  * @hw: pointer to the HW structure
     507                 :            :  * @msg: The message buffer
     508                 :            :  * @size: Length of buffer
     509                 :            :  * @mbx_id: id of mailbox to write
     510                 :            :  *
     511                 :            :  * returns SUCCESS if it successfully copied message into the buffer
     512                 :            :  **/
     513                 :          0 : STATIC s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
     514                 :            :                               u16 mbx_id)
     515                 :            : {
     516                 :            :         u32 vf_mailbox;
     517                 :            :         s32 ret_val;
     518                 :            :         u16 i;
     519                 :            : 
     520                 :            :         UNREFERENCED_1PARAMETER(mbx_id);
     521                 :            : 
     522                 :          0 :         DEBUGFUNC("ixgbe_write_mbx_vf");
     523                 :            : 
     524                 :            :         /* lock the mailbox to prevent pf/vf race condition */
     525                 :          0 :         ret_val = ixgbe_obtain_mbx_lock_vf(hw);
     526         [ #  # ]:          0 :         if (ret_val)
     527                 :          0 :                 goto out;
     528                 :            : 
     529                 :            :         /* flush msg and acks as we are overwriting the message buffer */
     530                 :            :         ixgbe_clear_msg_vf(hw);
     531                 :            :         ixgbe_clear_ack_vf(hw);
     532                 :            : 
     533                 :            :         /* copy the caller specified message to the mailbox memory buffer */
     534         [ #  # ]:          0 :         for (i = 0; i < size; i++)
     535                 :          0 :                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
     536                 :            : 
     537                 :            :         /* update stats */
     538                 :          0 :         hw->mbx.stats.msgs_tx++;
     539                 :            : 
     540                 :            :         /* interrupt the PF to tell it a message has been sent */
     541                 :            :         vf_mailbox = ixgbe_read_mailbox_vf(hw);
     542                 :          0 :         vf_mailbox |= IXGBE_VFMAILBOX_REQ;
     543                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
     544                 :            : 
     545                 :            :         /* if msg sent wait until we receive an ack */
     546                 :          0 :         ixgbe_poll_for_ack(hw, mbx_id);
     547                 :            : 
     548                 :          0 : out:
     549                 :          0 :         hw->mbx.ops[mbx_id].release(hw, mbx_id);
     550                 :            : 
     551                 :          0 :         return ret_val;
     552                 :            : }
     553                 :            : 
     554                 :            : /**
     555                 :            :  * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf
     556                 :            :  * @hw: pointer to the HW structure
     557                 :            :  * @msg: The message buffer
     558                 :            :  * @size: Length of buffer
     559                 :            :  * @mbx_id: id of mailbox to read
     560                 :            :  *
     561                 :            :  * returns SUCCESS if it successfully read message from buffer
     562                 :            :  **/
     563                 :          0 : STATIC s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
     564                 :            :                                     u16 mbx_id)
     565                 :            : {
     566                 :            :         s32 ret_val;
     567                 :            :         u16 i;
     568                 :            : 
     569                 :          0 :         DEBUGFUNC("ixgbe_read_mbx_vf_legacy");
     570                 :            :         UNREFERENCED_1PARAMETER(mbx_id);
     571                 :            : 
     572                 :            :         /* lock the mailbox to prevent pf/vf race condition */
     573                 :          0 :         ret_val = ixgbe_obtain_mbx_lock_vf(hw);
     574         [ #  # ]:          0 :         if (ret_val)
     575                 :            :                 return ret_val;
     576                 :            : 
     577                 :            :         /* copy the message from the mailbox memory buffer */
     578         [ #  # ]:          0 :         for (i = 0; i < size; i++)
     579                 :          0 :                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
     580                 :            : 
     581                 :            :         /* Acknowledge receipt and release mailbox, then we're done */
     582                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
     583                 :            : 
     584                 :            :         /* update stats */
     585                 :          0 :         hw->mbx.stats.msgs_rx++;
     586                 :            : 
     587                 :          0 :         return IXGBE_SUCCESS;
     588                 :            : }
     589                 :            : 
     590                 :            : /**
     591                 :            :  * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
     592                 :            :  * @hw: pointer to the HW structure
     593                 :            :  * @msg: The message buffer
     594                 :            :  * @size: Length of buffer
     595                 :            :  * @mbx_id: id of mailbox to read
     596                 :            :  *
     597                 :            :  * returns SUCCESS if it successfully read message from buffer
     598                 :            :  **/
     599                 :          0 : STATIC s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
     600                 :            :                              u16 mbx_id)
     601                 :            : {
     602                 :            :         u32 vf_mailbox;
     603                 :            :         s32 ret_val;
     604                 :            :         u16 i;
     605                 :            : 
     606                 :          0 :         DEBUGFUNC("ixgbe_read_mbx_vf");
     607                 :            :         UNREFERENCED_1PARAMETER(mbx_id);
     608                 :            : 
     609                 :            :         /* check if there is a message from PF */
     610                 :          0 :         ret_val = ixgbe_check_for_msg_vf(hw, 0);
     611         [ #  # ]:          0 :         if (ret_val != IXGBE_SUCCESS)
     612                 :            :                 return IXGBE_ERR_MBX_NOMSG;
     613                 :            : 
     614                 :            :         ixgbe_clear_msg_vf(hw);
     615                 :            : 
     616                 :            :         /* copy the message from the mailbox memory buffer */
     617         [ #  # ]:          0 :         for (i = 0; i < size; i++)
     618                 :          0 :                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
     619                 :            : 
     620                 :            :         /* Acknowledge receipt */
     621                 :            :         vf_mailbox = ixgbe_read_mailbox_vf(hw);
     622                 :          0 :         vf_mailbox |= IXGBE_VFMAILBOX_ACK;
     623                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
     624                 :            : 
     625                 :            :         /* update stats */
     626                 :          0 :         hw->mbx.stats.msgs_rx++;
     627                 :            : 
     628                 :          0 :         return IXGBE_SUCCESS;
     629                 :            : }
     630                 :            : 
     631                 :            : /**
     632                 :            :  * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
     633                 :            :  * @hw: pointer to the HW structure
     634                 :            :  *
     635                 :            :  * Initializes single set the hw->mbx struct to correct values for vf mailbox
     636                 :            :  * Set of legacy functions is being used here
     637                 :            :  */
     638                 :          0 : void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
     639                 :            : {
     640                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     641                 :            : 
     642                 :          0 :         mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
     643                 :          0 :         mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
     644                 :            : 
     645                 :          0 :         mbx->size = IXGBE_VFMAILBOX_SIZE;
     646                 :            : 
     647                 :            :         /* VF has only one mailbox connection, no need for more IDs */
     648                 :          0 :         mbx->ops[0].release = ixgbe_release_mbx_lock_dummy;
     649                 :          0 :         mbx->ops[0].read = ixgbe_read_mbx_vf_legacy;
     650                 :          0 :         mbx->ops[0].write = ixgbe_write_mbx_vf_legacy;
     651                 :          0 :         mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
     652                 :          0 :         mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
     653                 :          0 :         mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
     654                 :          0 :         mbx->ops[0].clear = NULL;
     655                 :            : 
     656                 :          0 :         mbx->stats.msgs_tx = 0;
     657                 :          0 :         mbx->stats.msgs_rx = 0;
     658                 :          0 :         mbx->stats.reqs = 0;
     659                 :          0 :         mbx->stats.acks = 0;
     660                 :          0 :         mbx->stats.rsts = 0;
     661                 :          0 : }
     662                 :            : 
     663                 :            : /**
     664                 :            :  * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox
     665                 :            :  * @hw: pointer to the HW structure
     666                 :            :  *
     667                 :            :  * Initializes the hw->mbx struct to correct values for vf mailbox
     668                 :            :  */
     669                 :          0 : void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw)
     670                 :            : {
     671                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     672                 :            : 
     673                 :          0 :         mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
     674                 :          0 :         mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
     675                 :            : 
     676                 :          0 :         mbx->size = IXGBE_VFMAILBOX_SIZE;
     677                 :            : 
     678                 :            :         /* VF has only one mailbox connection, no need for more IDs */
     679                 :          0 :         mbx->ops[0].release = ixgbe_release_mbx_lock_vf;
     680                 :          0 :         mbx->ops[0].read = ixgbe_read_mbx_vf;
     681                 :          0 :         mbx->ops[0].write = ixgbe_write_mbx_vf;
     682                 :          0 :         mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
     683                 :          0 :         mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
     684                 :          0 :         mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
     685                 :          0 :         mbx->ops[0].clear = NULL;
     686                 :            : 
     687                 :          0 :         mbx->stats.msgs_tx = 0;
     688                 :          0 :         mbx->stats.msgs_rx = 0;
     689                 :          0 :         mbx->stats.reqs = 0;
     690                 :          0 :         mbx->stats.acks = 0;
     691                 :          0 :         mbx->stats.rsts = 0;
     692                 :          0 : }
     693                 :            : 
     694                 :            : STATIC void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
     695                 :            : {
     696                 :          0 :         u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
     697                 :          0 :         s32 index = IXGBE_PFMBICR_INDEX(vf_id);
     698                 :            :         u32 pfmbicr;
     699                 :            : 
     700                 :          0 :         pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
     701                 :            : 
     702   [ #  #  #  #  :          0 :         if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift))
                   #  # ]
     703                 :          0 :                 hw->mbx.stats.reqs++;
     704                 :            : 
     705                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
     706                 :            :                         IXGBE_PFMBICR_VFREQ_VF1 << vf_shift);
     707                 :            : }
     708                 :            : 
     709                 :            : STATIC void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
     710                 :            : {
     711                 :            :         u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
     712                 :            :         s32 index = IXGBE_PFMBICR_INDEX(vf_id);
     713                 :            :         u32 pfmbicr;
     714                 :            : 
     715                 :          0 :         pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
     716                 :            : 
     717   [ #  #  #  #  :          0 :         if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift))
                   #  # ]
     718                 :          0 :                 hw->mbx.stats.acks++;
     719                 :            : 
     720                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
     721                 :            :                         IXGBE_PFMBICR_VFACK_VF1 << vf_shift);
     722                 :          0 : }
     723                 :            : 
     724                 :            : STATIC s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
     725                 :            : {
     726                 :          0 :         u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
     727                 :            : 
     728   [ #  #  #  # ]:          0 :         if (pfmbicr & mask)
     729                 :            :                 return IXGBE_SUCCESS;
     730                 :            : 
     731                 :            :         return IXGBE_ERR_MBX;
     732                 :            : }
     733                 :            : 
     734                 :            : /**
     735                 :            :  * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
     736                 :            :  * @hw: pointer to the HW structure
     737                 :            :  * @vf_id: the VF index
     738                 :            :  *
     739                 :            :  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
     740                 :            :  **/
     741                 :          0 : STATIC s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
     742                 :            : {
     743                 :          0 :         u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
     744                 :          0 :         s32 index = IXGBE_PFMBICR_INDEX(vf_id);
     745                 :            : 
     746                 :          0 :         DEBUGFUNC("ixgbe_check_for_msg_pf");
     747                 :            : 
     748                 :          0 :         if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift,
     749                 :            :                                     index))
     750                 :          0 :                 return IXGBE_SUCCESS;
     751                 :            : 
     752                 :            :         return IXGBE_ERR_MBX;
     753                 :            : }
     754                 :            : 
     755                 :            : /**
     756                 :            :  * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
     757                 :            :  * @hw: pointer to the HW structure
     758                 :            :  * @vf_id: the VF index
     759                 :            :  *
     760                 :            :  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
     761                 :            :  **/
     762                 :          0 : STATIC s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
     763                 :            : {
     764                 :          0 :         u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
     765                 :          0 :         s32 index = IXGBE_PFMBICR_INDEX(vf_id);
     766                 :            :         s32 ret_val = IXGBE_ERR_MBX;
     767                 :            : 
     768                 :          0 :         DEBUGFUNC("ixgbe_check_for_ack_pf");
     769                 :            : 
     770                 :          0 :         if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift,
     771                 :            :                                     index)) {
     772                 :            :                 ret_val = IXGBE_SUCCESS;
     773                 :            :                 /* TODO: should this be autocleared? */
     774                 :            :                 ixgbe_clear_ack_pf(hw, vf_id);
     775                 :            :         }
     776                 :            : 
     777                 :          0 :         return ret_val;
     778                 :            : }
     779                 :            : 
     780                 :            : /**
     781                 :            :  * ixgbe_check_for_rst_pf - checks to see if the VF has reset
     782                 :            :  * @hw: pointer to the HW structure
     783                 :            :  * @vf_id: the VF index
     784                 :            :  *
     785                 :            :  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
     786                 :            :  **/
     787                 :          0 : STATIC s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)
     788                 :            : {
     789                 :          0 :         u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id);
     790                 :          0 :         u32 index = IXGBE_PFVFLRE_INDEX(vf_id);
     791                 :            :         s32 ret_val = IXGBE_ERR_MBX;
     792                 :            :         u32 vflre = 0;
     793                 :            : 
     794                 :          0 :         DEBUGFUNC("ixgbe_check_for_rst_pf");
     795                 :            : 
     796      [ #  #  # ]:          0 :         switch (hw->mac.type) {
     797                 :          0 :         case ixgbe_mac_82599EB:
     798         [ #  # ]:          0 :                 vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLRE(index));
     799                 :          0 :                 break;
     800                 :          0 :         case ixgbe_mac_X550:
     801                 :            :         case ixgbe_mac_X550EM_x:
     802                 :            :         case ixgbe_mac_X550EM_a:
     803                 :            :         case ixgbe_mac_X540:
     804                 :            :         case ixgbe_mac_E610:
     805                 :          0 :                 vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index));
     806                 :          0 :                 break;
     807                 :            :         default:
     808                 :            :                 break;
     809                 :            :         }
     810                 :            : 
     811         [ #  # ]:          0 :         if (vflre & (1 << vf_shift)) {
     812                 :            :                 ret_val = IXGBE_SUCCESS;
     813                 :          0 :                 IXGBE_WRITE_REG(hw, IXGBE_PFVFLREC(index), (1 << vf_shift));
     814                 :          0 :                 hw->mbx.stats.rsts++;
     815                 :            :         }
     816                 :            : 
     817                 :          0 :         return ret_val;
     818                 :            : }
     819                 :            : 
     820                 :            : /**
     821                 :            :  * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
     822                 :            :  * @hw: pointer to the HW structure
     823                 :            :  * @vf_id: the VF index
     824                 :            :  *
     825                 :            :  * return SUCCESS if we obtained the mailbox lock
     826                 :            :  **/
     827                 :          0 : STATIC s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
     828                 :            : {
     829                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
     830                 :          0 :         int countdown = mbx->timeout;
     831                 :            :         s32 ret_val = IXGBE_ERR_MBX;
     832                 :            :         u32 pf_mailbox;
     833                 :            : 
     834                 :          0 :         DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
     835                 :            : 
     836         [ #  # ]:          0 :         if (!mbx->timeout)
     837                 :            :                 return IXGBE_ERR_CONFIG;
     838                 :            : 
     839         [ #  # ]:          0 :         while (countdown--) {
     840                 :            :                 /* Reserve mailbox for PF use */
     841                 :          0 :                 pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
     842                 :            : 
     843                 :            :                 /* Check if other thread holds the PF lock already */
     844         [ #  # ]:          0 :                 if (pf_mailbox & IXGBE_PFMAILBOX_PFU)
     845                 :          0 :                         goto retry;
     846                 :            : 
     847                 :          0 :                 pf_mailbox |= IXGBE_PFMAILBOX_PFU;
     848                 :          0 :                 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
     849                 :            : 
     850                 :            :                 /* Verify that PF is the owner of the lock */
     851                 :          0 :                 pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
     852         [ #  # ]:          0 :                 if (pf_mailbox & IXGBE_PFMAILBOX_PFU) {
     853                 :            :                         ret_val = IXGBE_SUCCESS;
     854                 :            :                         break;
     855                 :            :                 }
     856                 :            : 
     857                 :          0 :         retry:
     858                 :            :                 /* Wait a bit before trying again */
     859                 :          0 :                 usec_delay(mbx->usec_delay);
     860                 :            :         }
     861                 :            : 
     862         [ #  # ]:          0 :         if (ret_val != IXGBE_SUCCESS) {
     863                 :          0 :                 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
     864                 :            :                               "Failed to obtain mailbox lock");
     865                 :            :                 ret_val = IXGBE_ERR_TIMEOUT;
     866                 :            :         }
     867                 :            : 
     868                 :            :         return ret_val;
     869                 :            : }
     870                 :            : 
     871                 :            : /**
     872                 :            :  * ixgbe_release_mbx_lock_pf - release mailbox lock
     873                 :            :  * @hw: pointer to the HW structure
     874                 :            :  * @vf_id: the VF index
     875                 :            :  **/
     876                 :          0 : STATIC void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
     877                 :            : {
     878                 :            :         u32 pf_mailbox;
     879                 :            : 
     880                 :          0 :         DEBUGFUNC("ixgbe_release_mbx_lock_pf");
     881                 :            : 
     882                 :            :         /* Return ownership of the buffer */
     883                 :          0 :         pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
     884                 :          0 :         pf_mailbox &= ~IXGBE_PFMAILBOX_PFU;
     885                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
     886                 :          0 : }
     887                 :            : 
     888                 :            : /**
     889                 :            :  * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox
     890                 :            :  * @hw: pointer to the HW structure
     891                 :            :  * @msg: The message buffer
     892                 :            :  * @size: Length of buffer
     893                 :            :  * @vf_id: the VF index
     894                 :            :  *
     895                 :            :  * returns SUCCESS if it successfully copied message into the buffer
     896                 :            :  **/
     897                 :          0 : STATIC s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
     898                 :            :                                      u16 vf_id)
     899                 :            : {
     900                 :            :         s32 ret_val;
     901                 :            :         u16 i;
     902                 :            : 
     903                 :          0 :         DEBUGFUNC("ixgbe_write_mbx_pf_legacy");
     904                 :            : 
     905                 :            :         /* lock the mailbox to prevent pf/vf race condition */
     906                 :          0 :         ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
     907         [ #  # ]:          0 :         if (ret_val)
     908                 :            :                 return ret_val;
     909                 :            : 
     910                 :            :         /* flush msg and acks as we are overwriting the message buffer */
     911                 :          0 :         ixgbe_check_for_msg_pf(hw, vf_id);
     912                 :            :         ixgbe_clear_msg_pf(hw, vf_id);
     913                 :          0 :         ixgbe_check_for_ack_pf(hw, vf_id);
     914                 :            :         ixgbe_clear_ack_pf(hw, vf_id);
     915                 :            : 
     916                 :            :         /* copy the caller specified message to the mailbox memory buffer */
     917         [ #  # ]:          0 :         for (i = 0; i < size; i++)
     918                 :          0 :                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
     919                 :            : 
     920                 :            :         /* Interrupt VF to tell it a message has been sent and release buffer*/
     921                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS);
     922                 :            : 
     923                 :            :         /* update stats */
     924                 :          0 :         hw->mbx.stats.msgs_tx++;
     925                 :            : 
     926                 :          0 :         return IXGBE_SUCCESS;
     927                 :            : }
     928                 :            : 
     929                 :            : /**
     930                 :            :  * ixgbe_write_mbx_pf - Places a message in the mailbox
     931                 :            :  * @hw: pointer to the HW structure
     932                 :            :  * @msg: The message buffer
     933                 :            :  * @size: Length of buffer
     934                 :            :  * @vf_id: the VF index
     935                 :            :  *
     936                 :            :  * returns SUCCESS if it successfully copied message into the buffer
     937                 :            :  **/
     938                 :          0 : STATIC s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
     939                 :            :                               u16 vf_id)
     940                 :            : {
     941                 :            :         u32 pf_mailbox;
     942                 :            :         s32 ret_val;
     943                 :            :         u16 i;
     944                 :            : 
     945                 :          0 :         DEBUGFUNC("ixgbe_write_mbx_pf");
     946                 :            : 
     947                 :            :         /* lock the mailbox to prevent pf/vf race condition */
     948                 :          0 :         ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
     949         [ #  # ]:          0 :         if (ret_val)
     950                 :          0 :                 goto out;
     951                 :            : 
     952                 :            :         /* flush msg and acks as we are overwriting the message buffer */
     953                 :            :         ixgbe_clear_msg_pf(hw, vf_id);
     954                 :            :         ixgbe_clear_ack_pf(hw, vf_id);
     955                 :            : 
     956                 :            :         /* copy the caller specified message to the mailbox memory buffer */
     957         [ #  # ]:          0 :         for (i = 0; i < size; i++)
     958                 :          0 :                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
     959                 :            : 
     960                 :            :         /* interrupt VF to tell it a message has been sent */
     961                 :          0 :         pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
     962                 :          0 :         pf_mailbox |= IXGBE_PFMAILBOX_STS;
     963                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
     964                 :            : 
     965                 :            :         /* if msg sent wait until we receive an ack */
     966         [ #  # ]:          0 :         if (msg[0] & IXGBE_VT_MSGTYPE_CTS)
     967                 :          0 :                 ixgbe_poll_for_ack(hw, vf_id);
     968                 :            : 
     969                 :            :         /* update stats */
     970                 :          0 :         hw->mbx.stats.msgs_tx++;
     971                 :            : 
     972                 :          0 : out:
     973                 :          0 :         hw->mbx.ops[vf_id].release(hw, vf_id);
     974                 :            : 
     975                 :          0 :         return ret_val;
     976                 :            : 
     977                 :            : }
     978                 :            : 
     979                 :            : /**
     980                 :            :  * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox
     981                 :            :  * @hw: pointer to the HW structure
     982                 :            :  * @msg: The message buffer
     983                 :            :  * @size: Length of buffer
     984                 :            :  * @vf_id: the VF index
     985                 :            :  *
     986                 :            :  * This function copies a message from the mailbox buffer to the caller's
     987                 :            :  * memory buffer.  The presumption is that the caller knows that there was
     988                 :            :  * a message due to a VF request so no polling for message is needed.
     989                 :            :  **/
     990                 :          0 : STATIC s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
     991                 :            :                                     u16 vf_id)
     992                 :            : {
     993                 :            :         s32 ret_val;
     994                 :            :         u16 i;
     995                 :            : 
     996                 :          0 :         DEBUGFUNC("ixgbe_read_mbx_pf_legacy");
     997                 :            : 
     998                 :            :         /* lock the mailbox to prevent pf/vf race condition */
     999                 :          0 :         ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
    1000         [ #  # ]:          0 :         if (ret_val != IXGBE_SUCCESS)
    1001                 :            :                 return ret_val;
    1002                 :            : 
    1003                 :            :         /* copy the message to the mailbox memory buffer */
    1004         [ #  # ]:          0 :         for (i = 0; i < size; i++)
    1005                 :          0 :                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
    1006                 :            : 
    1007                 :            :         /* Acknowledge the message and release buffer */
    1008                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK);
    1009                 :            : 
    1010                 :            :         /* update stats */
    1011                 :          0 :         hw->mbx.stats.msgs_rx++;
    1012                 :            : 
    1013                 :          0 :         return IXGBE_SUCCESS;
    1014                 :            : }
    1015                 :            : 
    1016                 :            : /**
    1017                 :            :  * ixgbe_read_mbx_pf - Read a message from the mailbox
    1018                 :            :  * @hw: pointer to the HW structure
    1019                 :            :  * @msg: The message buffer
    1020                 :            :  * @size: Length of buffer
    1021                 :            :  * @vf_id: the VF index
    1022                 :            :  *
    1023                 :            :  * This function copies a message from the mailbox buffer to the caller's
    1024                 :            :  * memory buffer.  The presumption is that the caller knows that there was
    1025                 :            :  * a message due to a VF request so no polling for message is needed.
    1026                 :            :  **/
    1027                 :          0 : STATIC s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    1028                 :            :                              u16 vf_id)
    1029                 :            : {
    1030                 :            :         u32 pf_mailbox;
    1031                 :            :         s32 ret_val;
    1032                 :            :         u16 i;
    1033                 :            : 
    1034                 :          0 :         DEBUGFUNC("ixgbe_read_mbx_pf");
    1035                 :            : 
    1036                 :            :         /* check if there is a message from VF */
    1037                 :          0 :         ret_val = ixgbe_check_for_msg_pf(hw, vf_id);
    1038         [ #  # ]:          0 :         if (ret_val != IXGBE_SUCCESS)
    1039                 :            :                 return IXGBE_ERR_MBX_NOMSG;
    1040                 :            : 
    1041                 :            :         ixgbe_clear_msg_pf(hw, vf_id);
    1042                 :            : 
    1043                 :            :         /* copy the message to the mailbox memory buffer */
    1044         [ #  # ]:          0 :         for (i = 0; i < size; i++)
    1045                 :          0 :                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
    1046                 :            : 
    1047                 :            :         /* Acknowledge the message and release buffer */
    1048                 :          0 :         pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
    1049                 :          0 :         pf_mailbox |= IXGBE_PFMAILBOX_ACK;
    1050                 :          0 :         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
    1051                 :            : 
    1052                 :            :         /* update stats */
    1053                 :          0 :         hw->mbx.stats.msgs_rx++;
    1054                 :            : 
    1055                 :          0 :         return IXGBE_SUCCESS;
    1056                 :            : }
    1057                 :            : 
    1058                 :            : /**
    1059                 :            :  * ixgbe_clear_mbx_pf - Clear Mailbox Memory
    1060                 :            :  * @hw: pointer to the HW structure
    1061                 :            :  * @vf_id: the VF index
    1062                 :            :  *
    1063                 :            :  * Set VFMBMEM of given VF to 0x0.
    1064                 :            :  **/
    1065                 :          0 : STATIC s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id)
    1066                 :            : {
    1067                 :          0 :         u16 mbx_size = hw->mbx.size;
    1068                 :            :         u16 i;
    1069                 :            : 
    1070         [ #  # ]:          0 :         if (vf_id > 63)
    1071                 :            :                 return IXGBE_ERR_PARAM;
    1072                 :            : 
    1073         [ #  # ]:          0 :         for (i = 0; i < mbx_size; ++i)
    1074                 :          0 :                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, 0x0);
    1075                 :            : 
    1076                 :            :         return IXGBE_SUCCESS;
    1077                 :            : }
    1078                 :            : 
    1079                 :            : /**
    1080                 :            :  * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox
    1081                 :            :  * @hw: pointer to the HW structure
    1082                 :            :  * @vf_id: the VF index
    1083                 :            :  *
    1084                 :            :  * Initializes single set of the hw->mbx struct to correct values for pf mailbox
    1085                 :            :  * Set of legacy functions is being used here
    1086                 :            :  */
    1087                 :          0 : void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id)
    1088                 :            : {
    1089                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
    1090                 :            : 
    1091                 :          0 :         mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy;
    1092                 :          0 :         mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy;
    1093                 :          0 :         mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy;
    1094                 :          0 :         mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
    1095                 :          0 :         mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
    1096                 :          0 :         mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
    1097                 :          0 :         mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
    1098                 :          0 : }
    1099                 :            : 
    1100                 :            : /**
    1101                 :            :  * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
    1102                 :            :  * @hw: pointer to the HW structure
    1103                 :            :  *
    1104                 :            :  * Initializes all sets of the hw->mbx struct to correct values for pf
    1105                 :            :  * mailbox. One set corresponds to single VF. It also initializes counters
    1106                 :            :  * and general variables. A set of legacy functions is used by default.
    1107                 :            :  */
    1108                 :          0 : void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
    1109                 :            : {
    1110                 :            :         u16 i;
    1111                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
    1112                 :            : 
    1113                 :            :         /* Ensure we are not calling this function from VF */
    1114         [ #  # ]:          0 :         if (hw->mac.type != ixgbe_mac_82599EB &&
    1115                 :            :             hw->mac.type != ixgbe_mac_X550 &&
    1116                 :            :             hw->mac.type != ixgbe_mac_X550EM_x &&
    1117                 :            :             hw->mac.type != ixgbe_mac_X550EM_a &&
    1118                 :            :             hw->mac.type != ixgbe_mac_E610 &&
    1119                 :            :             hw->mac.type != ixgbe_mac_X540)
    1120                 :            :                 return;
    1121                 :            : 
    1122                 :            :         /* Initialize common mailbox settings */
    1123                 :          0 :         mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
    1124                 :          0 :         mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
    1125                 :          0 :         mbx->size = IXGBE_VFMAILBOX_SIZE;
    1126                 :            : 
    1127                 :            :         /* Initialize counters with zeroes */
    1128                 :          0 :         mbx->stats.msgs_tx = 0;
    1129                 :          0 :         mbx->stats.msgs_rx = 0;
    1130                 :          0 :         mbx->stats.reqs = 0;
    1131                 :          0 :         mbx->stats.acks = 0;
    1132                 :          0 :         mbx->stats.rsts = 0;
    1133                 :            : 
    1134                 :            :         /* No matter of VF number, we initialize params for all 64 VFs. */
    1135                 :            :         /* TODO: 1. Add a define for max VF and refactor SHARED to get rid
    1136                 :            :          * of magic number for that (63 or 64 depending on use case.)
    1137                 :            :          * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for
    1138                 :            :          * certain number of VFs instead of default maximum value of 64 (0..63)
    1139                 :            :          */
    1140         [ #  # ]:          0 :         for (i = 0; i < 64; i++)
    1141                 :          0 :                 ixgbe_init_mbx_params_pf_id(hw, i);
    1142                 :            : }
    1143                 :            : 
    1144                 :            : /**
    1145                 :            :  * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox
    1146                 :            :  * @hw: pointer to the HW structure
    1147                 :            :  * @vf_id: the VF index
    1148                 :            :  *
    1149                 :            :  * Initializes the hw->mbx struct to new function set for improved
    1150                 :            :  * stability and handling of messages.
    1151                 :            :  */
    1152                 :          0 : void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)
    1153                 :            : {
    1154                 :            :         struct ixgbe_mbx_info *mbx = &hw->mbx;
    1155                 :            : 
    1156                 :            :         /* Ensure we are not calling this function from VF */
    1157         [ #  # ]:          0 :         if (hw->mac.type != ixgbe_mac_82599EB &&
    1158                 :            :             hw->mac.type != ixgbe_mac_X550 &&
    1159                 :            :             hw->mac.type != ixgbe_mac_X550EM_x &&
    1160                 :            :             hw->mac.type != ixgbe_mac_X550EM_a &&
    1161                 :            :             hw->mac.type != ixgbe_mac_E610 &&
    1162                 :            :             hw->mac.type != ixgbe_mac_X540)
    1163                 :            :                 return;
    1164                 :            : 
    1165                 :          0 :         mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
    1166                 :          0 :         mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
    1167                 :          0 :         mbx->size = IXGBE_VFMAILBOX_SIZE;
    1168                 :            : 
    1169                 :          0 :         mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf;
    1170                 :          0 :         mbx->ops[vf_id].read = ixgbe_read_mbx_pf;
    1171                 :          0 :         mbx->ops[vf_id].write = ixgbe_write_mbx_pf;
    1172                 :          0 :         mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
    1173                 :          0 :         mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
    1174                 :          0 :         mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
    1175                 :          0 :         mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
    1176                 :            : 
    1177                 :          0 :         mbx->stats.msgs_tx = 0;
    1178                 :          0 :         mbx->stats.msgs_rx = 0;
    1179                 :          0 :         mbx->stats.reqs = 0;
    1180                 :          0 :         mbx->stats.acks = 0;
    1181                 :          0 :         mbx->stats.rsts = 0;
    1182                 :            : }

Generated by: LCOV version 1.14