The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ixgbe/ixgbe_mbx.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /******************************************************************************
    2   SPDX-License-Identifier: BSD-3-Clause
    3 
    4   Copyright (c) 2001-2020, Intel Corporation
    5   All rights reserved.
    6 
    7   Redistribution and use in source and binary forms, with or without
    8   modification, are permitted provided that the following conditions are met:
    9 
   10    1. Redistributions of source code must retain the above copyright notice,
   11       this list of conditions and the following disclaimer.
   12 
   13    2. Redistributions in binary form must reproduce the above copyright
   14       notice, this list of conditions and the following disclaimer in the
   15       documentation and/or other materials provided with the distribution.
   16 
   17    3. Neither the name of the Intel Corporation nor the names of its
   18       contributors may be used to endorse or promote products derived from
   19       this software without specific prior written permission.
   20 
   21   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   22   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   25   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   26   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   27   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   29   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   30   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   31   POSSIBILITY OF SUCH DAMAGE.
   32 
   33 ******************************************************************************/
   34 /*$FreeBSD$*/
   35 
   36 #include "ixgbe_type.h"
   37 #include "ixgbe_mbx.h"
   38 
   39 /**
   40  * ixgbe_read_mbx - Reads a message from the mailbox
   41  * @hw: pointer to the HW structure
   42  * @msg: The message buffer
   43  * @size: Length of buffer
   44  * @mbx_id: id of mailbox to read
   45  *
   46  * returns SUCCESS if it successfully read message from buffer
   47  **/
   48 s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
   49 {
   50         struct ixgbe_mbx_info *mbx = &hw->mbx;
   51         s32 ret_val = IXGBE_ERR_MBX;
   52 
   53         DEBUGFUNC("ixgbe_read_mbx");
   54 
   55         /* limit read to size of mailbox */
   56         if (size > mbx->size)
   57                 size = mbx->size;
   58 
   59         if (mbx->ops.read)
   60                 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
   61 
   62         return ret_val;
   63 }
   64 
   65 /**
   66  * ixgbe_write_mbx - Write a message to the mailbox
   67  * @hw: pointer to the HW structure
   68  * @msg: The message buffer
   69  * @size: Length of buffer
   70  * @mbx_id: id of mailbox to write
   71  *
   72  * returns SUCCESS if it successfully copied message into the buffer
   73  **/
   74 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
   75 {
   76         struct ixgbe_mbx_info *mbx = &hw->mbx;
   77         s32 ret_val = IXGBE_SUCCESS;
   78 
   79         DEBUGFUNC("ixgbe_write_mbx");
   80 
   81         if (size > mbx->size) {
   82                 ret_val = IXGBE_ERR_MBX;
   83                 ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
   84                              "Invalid mailbox message size %d", size);
   85         } else if (mbx->ops.write)
   86                 ret_val = mbx->ops.write(hw, msg, size, mbx_id);
   87 
   88         return ret_val;
   89 }
   90 
   91 /**
   92  * ixgbe_check_for_msg - checks to see if someone sent us mail
   93  * @hw: pointer to the HW structure
   94  * @mbx_id: id of mailbox to check
   95  *
   96  * returns SUCCESS if the Status bit was found or else ERR_MBX
   97  **/
   98 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
   99 {
  100         struct ixgbe_mbx_info *mbx = &hw->mbx;
  101         s32 ret_val = IXGBE_ERR_MBX;
  102 
  103         DEBUGFUNC("ixgbe_check_for_msg");
  104 
  105         if (mbx->ops.check_for_msg)
  106                 ret_val = mbx->ops.check_for_msg(hw, mbx_id);
  107 
  108         return ret_val;
  109 }
  110 
  111 /**
  112  * ixgbe_check_for_ack - checks to see if someone sent us ACK
  113  * @hw: pointer to the HW structure
  114  * @mbx_id: id of mailbox to check
  115  *
  116  * returns SUCCESS if the Status bit was found or else ERR_MBX
  117  **/
  118 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
  119 {
  120         struct ixgbe_mbx_info *mbx = &hw->mbx;
  121         s32 ret_val = IXGBE_ERR_MBX;
  122 
  123         DEBUGFUNC("ixgbe_check_for_ack");
  124 
  125         if (mbx->ops.check_for_ack)
  126                 ret_val = mbx->ops.check_for_ack(hw, mbx_id);
  127 
  128         return ret_val;
  129 }
  130 
  131 /**
  132  * ixgbe_check_for_rst - checks to see if other side has reset
  133  * @hw: pointer to the HW structure
  134  * @mbx_id: id of mailbox to check
  135  *
  136  * returns SUCCESS if the Status bit was found or else ERR_MBX
  137  **/
  138 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
  139 {
  140         struct ixgbe_mbx_info *mbx = &hw->mbx;
  141         s32 ret_val = IXGBE_ERR_MBX;
  142 
  143         DEBUGFUNC("ixgbe_check_for_rst");
  144 
  145         if (mbx->ops.check_for_rst)
  146                 ret_val = mbx->ops.check_for_rst(hw, mbx_id);
  147 
  148         return ret_val;
  149 }
  150 
  151 /**
  152  * ixgbe_poll_for_msg - Wait for message notification
  153  * @hw: pointer to the HW structure
  154  * @mbx_id: id of mailbox to write
  155  *
  156  * returns SUCCESS if it successfully received a message notification
  157  **/
  158 static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
  159 {
  160         struct ixgbe_mbx_info *mbx = &hw->mbx;
  161         int countdown = mbx->timeout;
  162 
  163         DEBUGFUNC("ixgbe_poll_for_msg");
  164 
  165         if (!countdown || !mbx->ops.check_for_msg)
  166                 goto out;
  167 
  168         while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
  169                 countdown--;
  170                 if (!countdown)
  171                         break;
  172                 usec_delay(mbx->usec_delay);
  173         }
  174 
  175         if (countdown == 0)
  176                 ERROR_REPORT2(IXGBE_ERROR_POLLING,
  177                            "Polling for VF%d mailbox message timedout", mbx_id);
  178 
  179 out:
  180         return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
  181 }
  182 
  183 /**
  184  * ixgbe_poll_for_ack - Wait for message acknowledgment
  185  * @hw: pointer to the HW structure
  186  * @mbx_id: id of mailbox to write
  187  *
  188  * returns SUCCESS if it successfully received a message acknowledgment
  189  **/
  190 static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
  191 {
  192         struct ixgbe_mbx_info *mbx = &hw->mbx;
  193         int countdown = mbx->timeout;
  194 
  195         DEBUGFUNC("ixgbe_poll_for_ack");
  196 
  197         if (!countdown || !mbx->ops.check_for_ack)
  198                 goto out;
  199 
  200         while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
  201                 countdown--;
  202                 if (!countdown)
  203                         break;
  204                 usec_delay(mbx->usec_delay);
  205         }
  206 
  207         if (countdown == 0)
  208                 ERROR_REPORT2(IXGBE_ERROR_POLLING,
  209                              "Polling for VF%d mailbox ack timedout", mbx_id);
  210 
  211 out:
  212         return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
  213 }
  214 
  215 /**
  216  * ixgbe_read_posted_mbx - Wait for message notification and receive message
  217  * @hw: pointer to the HW structure
  218  * @msg: The message buffer
  219  * @size: Length of buffer
  220  * @mbx_id: id of mailbox to write
  221  *
  222  * returns SUCCESS if it successfully received a message notification and
  223  * copied it into the receive buffer.
  224  **/
  225 s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
  226                                  u16 mbx_id)
  227 {
  228         struct ixgbe_mbx_info *mbx = &hw->mbx;
  229         s32 ret_val = IXGBE_ERR_MBX;
  230 
  231         DEBUGFUNC("ixgbe_read_posted_mbx");
  232 
  233         if (!mbx->ops.read)
  234                 goto out;
  235 
  236         ret_val = ixgbe_poll_for_msg(hw, mbx_id);
  237 
  238         /* if ack received read message, otherwise we timed out */
  239         if (!ret_val)
  240                 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
  241 out:
  242         return ret_val;
  243 }
  244 
  245 /**
  246  * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
  247  * @hw: pointer to the HW structure
  248  * @msg: The message buffer
  249  * @size: Length of buffer
  250  * @mbx_id: id of mailbox to write
  251  *
  252  * returns SUCCESS if it successfully copied message into the buffer and
  253  * received an ack to that message within delay * timeout period
  254  **/
  255 s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
  256                                   u16 mbx_id)
  257 {
  258         struct ixgbe_mbx_info *mbx = &hw->mbx;
  259         s32 ret_val = IXGBE_ERR_MBX;
  260 
  261         DEBUGFUNC("ixgbe_write_posted_mbx");
  262 
  263         /* exit if either we can't write or there isn't a defined timeout */
  264         if (!mbx->ops.write || !mbx->timeout)
  265                 goto out;
  266 
  267         /* send msg */
  268         ret_val = mbx->ops.write(hw, msg, size, mbx_id);
  269 
  270         /* if msg sent wait until we receive an ack */
  271         if (!ret_val)
  272                 ret_val = ixgbe_poll_for_ack(hw, mbx_id);
  273 out:
  274         return ret_val;
  275 }
  276 
  277 /**
  278  * ixgbe_init_mbx_ops_generic - Initialize MB function pointers
  279  * @hw: pointer to the HW structure
  280  *
  281  * Setups up the mailbox read and write message function pointers
  282  **/
  283 void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
  284 {
  285         struct ixgbe_mbx_info *mbx = &hw->mbx;
  286 
  287         mbx->ops.read_posted = ixgbe_read_posted_mbx;
  288         mbx->ops.write_posted = ixgbe_write_posted_mbx;
  289 }
  290 
  291 /**
  292  * ixgbe_read_v2p_mailbox - read v2p mailbox
  293  * @hw: pointer to the HW structure
  294  *
  295  * This function is used to read the v2p mailbox without losing the read to
  296  * clear status bits.
  297  **/
  298 static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
  299 {
  300         u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
  301 
  302         v2p_mailbox |= hw->mbx.v2p_mailbox;
  303         hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
  304 
  305         return v2p_mailbox;
  306 }
  307 
  308 /**
  309  * ixgbe_check_for_bit_vf - Determine if a status bit was set
  310  * @hw: pointer to the HW structure
  311  * @mask: bitmask for bits to be tested and cleared
  312  *
  313  * This function is used to check for the read to clear bits within
  314  * the V2P mailbox.
  315  **/
  316 static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
  317 {
  318         u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
  319         s32 ret_val = IXGBE_ERR_MBX;
  320 
  321         if (v2p_mailbox & mask)
  322                 ret_val = IXGBE_SUCCESS;
  323 
  324         hw->mbx.v2p_mailbox &= ~mask;
  325 
  326         return ret_val;
  327 }
  328 
  329 /**
  330  * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
  331  * @hw: pointer to the HW structure
  332  * @mbx_id: id of mailbox to check
  333  *
  334  * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
  335  **/
  336 static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
  337 {
  338         s32 ret_val = IXGBE_ERR_MBX;
  339 
  340         UNREFERENCED_1PARAMETER(mbx_id);
  341         DEBUGFUNC("ixgbe_check_for_msg_vf");
  342 
  343         if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
  344                 ret_val = IXGBE_SUCCESS;
  345                 hw->mbx.stats.reqs++;
  346         }
  347 
  348         return ret_val;
  349 }
  350 
  351 /**
  352  * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
  353  * @hw: pointer to the HW structure
  354  * @mbx_id: id of mailbox to check
  355  *
  356  * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
  357  **/
  358 static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
  359 {
  360         s32 ret_val = IXGBE_ERR_MBX;
  361 
  362         UNREFERENCED_1PARAMETER(mbx_id);
  363         DEBUGFUNC("ixgbe_check_for_ack_vf");
  364 
  365         if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
  366                 ret_val = IXGBE_SUCCESS;
  367                 hw->mbx.stats.acks++;
  368         }
  369 
  370         return ret_val;
  371 }
  372 
  373 /**
  374  * ixgbe_check_for_rst_vf - checks to see if the PF has reset
  375  * @hw: pointer to the HW structure
  376  * @mbx_id: id of mailbox to check
  377  *
  378  * returns true if the PF has set the reset done bit or else false
  379  **/
  380 static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
  381 {
  382         s32 ret_val = IXGBE_ERR_MBX;
  383 
  384         UNREFERENCED_1PARAMETER(mbx_id);
  385         DEBUGFUNC("ixgbe_check_for_rst_vf");
  386 
  387         if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
  388             IXGBE_VFMAILBOX_RSTI))) {
  389                 ret_val = IXGBE_SUCCESS;
  390                 hw->mbx.stats.rsts++;
  391         }
  392 
  393         return ret_val;
  394 }
  395 
  396 /**
  397  * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
  398  * @hw: pointer to the HW structure
  399  *
  400  * return SUCCESS if we obtained the mailbox lock
  401  **/
  402 static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
  403 {
  404         s32 ret_val = IXGBE_ERR_MBX;
  405 
  406         DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
  407 
  408         /* Take ownership of the buffer */
  409         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
  410 
  411         /* reserve mailbox for vf use */
  412         if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
  413                 ret_val = IXGBE_SUCCESS;
  414 
  415         return ret_val;
  416 }
  417 
  418 /**
  419  * ixgbe_write_mbx_vf - Write a message to the mailbox
  420  * @hw: pointer to the HW structure
  421  * @msg: The message buffer
  422  * @size: Length of buffer
  423  * @mbx_id: id of mailbox to write
  424  *
  425  * returns SUCCESS if it successfully copied message into the buffer
  426  **/
  427 static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
  428                               u16 mbx_id)
  429 {
  430         s32 ret_val;
  431         u16 i;
  432 
  433         UNREFERENCED_1PARAMETER(mbx_id);
  434 
  435         DEBUGFUNC("ixgbe_write_mbx_vf");
  436 
  437         /* lock the mailbox to prevent pf/vf race condition */
  438         ret_val = ixgbe_obtain_mbx_lock_vf(hw);
  439         if (ret_val)
  440                 goto out_no_write;
  441 
  442         /* flush msg and acks as we are overwriting the message buffer */
  443         ixgbe_check_for_msg_vf(hw, 0);
  444         ixgbe_check_for_ack_vf(hw, 0);
  445 
  446         /* copy the caller specified message to the mailbox memory buffer */
  447         for (i = 0; i < size; i++)
  448                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
  449 
  450         /* update stats */
  451         hw->mbx.stats.msgs_tx++;
  452 
  453         /* Drop VFU and interrupt the PF to tell it a message has been sent */
  454         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
  455 
  456 out_no_write:
  457         return ret_val;
  458 }
  459 
  460 /**
  461  * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
  462  * @hw: pointer to the HW structure
  463  * @msg: The message buffer
  464  * @size: Length of buffer
  465  * @mbx_id: id of mailbox to read
  466  *
  467  * returns SUCCESS if it successfully read message from buffer
  468  **/
  469 static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
  470                              u16 mbx_id)
  471 {
  472         s32 ret_val = IXGBE_SUCCESS;
  473         u16 i;
  474 
  475         DEBUGFUNC("ixgbe_read_mbx_vf");
  476         UNREFERENCED_1PARAMETER(mbx_id);
  477 
  478         /* lock the mailbox to prevent pf/vf race condition */
  479         ret_val = ixgbe_obtain_mbx_lock_vf(hw);
  480         if (ret_val)
  481                 goto out_no_read;
  482 
  483         /* copy the message from the mailbox memory buffer */
  484         for (i = 0; i < size; i++)
  485                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
  486 
  487         /* Acknowledge receipt and release mailbox, then we're done */
  488         IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
  489 
  490         /* update stats */
  491         hw->mbx.stats.msgs_rx++;
  492 
  493 out_no_read:
  494         return ret_val;
  495 }
  496 
  497 /**
  498  * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
  499  * @hw: pointer to the HW structure
  500  *
  501  * Initializes the hw->mbx struct to correct values for vf mailbox
  502  */
  503 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
  504 {
  505         struct ixgbe_mbx_info *mbx = &hw->mbx;
  506 
  507         /* start mailbox as timed out and let the reset_hw call set the timeout
  508          * value to begin communications */
  509         mbx->timeout = 0;
  510         mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
  511 
  512         mbx->size = IXGBE_VFMAILBOX_SIZE;
  513 
  514         mbx->ops.read = ixgbe_read_mbx_vf;
  515         mbx->ops.write = ixgbe_write_mbx_vf;
  516         mbx->ops.read_posted = ixgbe_read_posted_mbx;
  517         mbx->ops.write_posted = ixgbe_write_posted_mbx;
  518         mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
  519         mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
  520         mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
  521 
  522         mbx->stats.msgs_tx = 0;
  523         mbx->stats.msgs_rx = 0;
  524         mbx->stats.reqs = 0;
  525         mbx->stats.acks = 0;
  526         mbx->stats.rsts = 0;
  527 }
  528 
  529 static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
  530 {
  531         u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
  532         s32 ret_val = IXGBE_ERR_MBX;
  533 
  534         if (mbvficr & mask) {
  535                 ret_val = IXGBE_SUCCESS;
  536                 IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
  537         }
  538 
  539         return ret_val;
  540 }
  541 
  542 /**
  543  * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
  544  * @hw: pointer to the HW structure
  545  * @vf_number: the VF index
  546  *
  547  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
  548  **/
  549 static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
  550 {
  551         s32 ret_val = IXGBE_ERR_MBX;
  552         s32 index = IXGBE_MBVFICR_INDEX(vf_number);
  553         u32 vf_bit = vf_number % 16;
  554 
  555         DEBUGFUNC("ixgbe_check_for_msg_pf");
  556 
  557         if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
  558                                     index)) {
  559                 ret_val = IXGBE_SUCCESS;
  560                 hw->mbx.stats.reqs++;
  561         }
  562 
  563         return ret_val;
  564 }
  565 
  566 /**
  567  * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
  568  * @hw: pointer to the HW structure
  569  * @vf_number: the VF index
  570  *
  571  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
  572  **/
  573 static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
  574 {
  575         s32 ret_val = IXGBE_ERR_MBX;
  576         s32 index = IXGBE_MBVFICR_INDEX(vf_number);
  577         u32 vf_bit = vf_number % 16;
  578 
  579         DEBUGFUNC("ixgbe_check_for_ack_pf");
  580 
  581         if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
  582                                     index)) {
  583                 ret_val = IXGBE_SUCCESS;
  584                 hw->mbx.stats.acks++;
  585         }
  586 
  587         return ret_val;
  588 }
  589 
  590 /**
  591  * ixgbe_check_for_rst_pf - checks to see if the VF has reset
  592  * @hw: pointer to the HW structure
  593  * @vf_number: the VF index
  594  *
  595  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
  596  **/
  597 static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
  598 {
  599         u32 reg_offset = (vf_number < 32) ? 0 : 1;
  600         u32 vf_shift = vf_number % 32;
  601         u32 vflre = 0;
  602         s32 ret_val = IXGBE_ERR_MBX;
  603 
  604         DEBUGFUNC("ixgbe_check_for_rst_pf");
  605 
  606         switch (hw->mac.type) {
  607         case ixgbe_mac_82599EB:
  608                 vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
  609                 break;
  610         case ixgbe_mac_X550:
  611         case ixgbe_mac_X550EM_x:
  612         case ixgbe_mac_X550EM_a:
  613         case ixgbe_mac_X540:
  614                 vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
  615                 break;
  616         default:
  617                 break;
  618         }
  619 
  620         if (vflre & (1 << vf_shift)) {
  621                 ret_val = IXGBE_SUCCESS;
  622                 IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
  623                 hw->mbx.stats.rsts++;
  624         }
  625 
  626         return ret_val;
  627 }
  628 
  629 /**
  630  * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
  631  * @hw: pointer to the HW structure
  632  * @vf_number: the VF index
  633  *
  634  * return SUCCESS if we obtained the mailbox lock
  635  **/
  636 static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
  637 {
  638         s32 ret_val = IXGBE_ERR_MBX;
  639         u32 p2v_mailbox;
  640 
  641         DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
  642 
  643         /* Take ownership of the buffer */
  644         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
  645 
  646         /* reserve mailbox for vf use */
  647         p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
  648         if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
  649                 ret_val = IXGBE_SUCCESS;
  650         else
  651                 ERROR_REPORT2(IXGBE_ERROR_POLLING,
  652                            "Failed to obtain mailbox lock for VF%d", vf_number);
  653 
  654 
  655         return ret_val;
  656 }
  657 
  658 /**
  659  * ixgbe_write_mbx_pf - Places a message in the mailbox
  660  * @hw: pointer to the HW structure
  661  * @msg: The message buffer
  662  * @size: Length of buffer
  663  * @vf_number: the VF index
  664  *
  665  * returns SUCCESS if it successfully copied message into the buffer
  666  **/
  667 static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
  668                               u16 vf_number)
  669 {
  670         s32 ret_val;
  671         u16 i;
  672 
  673         DEBUGFUNC("ixgbe_write_mbx_pf");
  674 
  675         /* lock the mailbox to prevent pf/vf race condition */
  676         ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
  677         if (ret_val)
  678                 goto out_no_write;
  679 
  680         /* flush msg and acks as we are overwriting the message buffer */
  681         ixgbe_check_for_msg_pf(hw, vf_number);
  682         ixgbe_check_for_ack_pf(hw, vf_number);
  683 
  684         /* copy the caller specified message to the mailbox memory buffer */
  685         for (i = 0; i < size; i++)
  686                 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
  687 
  688         /* Interrupt VF to tell it a message has been sent and release buffer*/
  689         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
  690 
  691         /* update stats */
  692         hw->mbx.stats.msgs_tx++;
  693 
  694 out_no_write:
  695         return ret_val;
  696 
  697 }
  698 
  699 /**
  700  * ixgbe_read_mbx_pf - Read a message from the mailbox
  701  * @hw: pointer to the HW structure
  702  * @msg: The message buffer
  703  * @size: Length of buffer
  704  * @vf_number: the VF index
  705  *
  706  * This function copies a message from the mailbox buffer to the caller's
  707  * memory buffer.  The presumption is that the caller knows that there was
  708  * a message due to a VF request so no polling for message is needed.
  709  **/
  710 static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
  711                              u16 vf_number)
  712 {
  713         s32 ret_val;
  714         u16 i;
  715 
  716         DEBUGFUNC("ixgbe_read_mbx_pf");
  717 
  718         /* lock the mailbox to prevent pf/vf race condition */
  719         ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
  720         if (ret_val)
  721                 goto out_no_read;
  722 
  723         /* copy the message to the mailbox memory buffer */
  724         for (i = 0; i < size; i++)
  725                 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
  726 
  727         /* Acknowledge the message and release buffer */
  728         IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
  729 
  730         /* update stats */
  731         hw->mbx.stats.msgs_rx++;
  732 
  733 out_no_read:
  734         return ret_val;
  735 }
  736 
  737 /**
  738  * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
  739  * @hw: pointer to the HW structure
  740  *
  741  * Initializes the hw->mbx struct to correct values for pf mailbox
  742  */
  743 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
  744 {
  745         struct ixgbe_mbx_info *mbx = &hw->mbx;
  746 
  747         if (hw->mac.type != ixgbe_mac_82599EB &&
  748             hw->mac.type != ixgbe_mac_X550 &&
  749             hw->mac.type != ixgbe_mac_X550EM_x &&
  750             hw->mac.type != ixgbe_mac_X550EM_a &&
  751             hw->mac.type != ixgbe_mac_X540)
  752                 return;
  753 
  754         mbx->timeout = 0;
  755         mbx->usec_delay = 0;
  756 
  757         mbx->size = IXGBE_VFMAILBOX_SIZE;
  758 
  759         mbx->ops.read = ixgbe_read_mbx_pf;
  760         mbx->ops.write = ixgbe_write_mbx_pf;
  761         mbx->ops.read_posted = ixgbe_read_posted_mbx;
  762         mbx->ops.write_posted = ixgbe_write_posted_mbx;
  763         mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
  764         mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
  765         mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
  766 
  767         mbx->stats.msgs_tx = 0;
  768         mbx->stats.msgs_rx = 0;
  769         mbx->stats.reqs = 0;
  770         mbx->stats.acks = 0;
  771         mbx->stats.rsts = 0;
  772 }

Cache object: d0a34e7625b2c23fe2547b1fed5889a7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.