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

Cache object: b1ac53f80ea1a6c29a700f81ec82edbe


[ 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.