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/e1000/e1000_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-2014, 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$*/
   34 
   35 #include "e1000_mbx.h"
   36 
   37 /**
   38  *  e1000_null_mbx_check_for_flag - No-op function, return 0
   39  *  @hw: pointer to the HW structure
   40  **/
   41 static s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw,
   42                                          u16 E1000_UNUSEDARG mbx_id)
   43 {
   44         DEBUGFUNC("e1000_null_mbx_check_flag");
   45 
   46         return E1000_SUCCESS;
   47 }
   48 
   49 /**
   50  *  e1000_null_mbx_transact - No-op function, return 0
   51  *  @hw: pointer to the HW structure
   52  **/
   53 static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw,
   54                                    u32 E1000_UNUSEDARG *msg,
   55                                    u16 E1000_UNUSEDARG size,
   56                                    u16 E1000_UNUSEDARG mbx_id)
   57 {
   58         DEBUGFUNC("e1000_null_mbx_rw_msg");
   59 
   60         return E1000_SUCCESS;
   61 }
   62 
   63 /**
   64  *  e1000_read_mbx - Reads a message from the mailbox
   65  *  @hw: pointer to the HW structure
   66  *  @msg: The message buffer
   67  *  @size: Length of buffer
   68  *  @mbx_id: id of mailbox to read
   69  *
   70  *  returns SUCCESS if it successfuly read message from buffer
   71  **/
   72 s32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
   73 {
   74         struct e1000_mbx_info *mbx = &hw->mbx;
   75         s32 ret_val = -E1000_ERR_MBX;
   76 
   77         DEBUGFUNC("e1000_read_mbx");
   78 
   79         /* limit read to size of mailbox */
   80         if (size > mbx->size)
   81                 size = mbx->size;
   82 
   83         if (mbx->ops.read)
   84                 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
   85 
   86         return ret_val;
   87 }
   88 
   89 /**
   90  *  e1000_write_mbx - Write a message to the mailbox
   91  *  @hw: pointer to the HW structure
   92  *  @msg: The message buffer
   93  *  @size: Length of buffer
   94  *  @mbx_id: id of mailbox to write
   95  *
   96  *  returns SUCCESS if it successfully copied message into the buffer
   97  **/
   98 s32 e1000_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
   99 {
  100         struct e1000_mbx_info *mbx = &hw->mbx;
  101         s32 ret_val = E1000_SUCCESS;
  102 
  103         DEBUGFUNC("e1000_write_mbx");
  104 
  105         if (size > mbx->size)
  106                 ret_val = -E1000_ERR_MBX;
  107 
  108         else if (mbx->ops.write)
  109                 ret_val = mbx->ops.write(hw, msg, size, mbx_id);
  110 
  111         return ret_val;
  112 }
  113 
  114 /**
  115  *  e1000_check_for_msg - checks to see if someone sent us mail
  116  *  @hw: pointer to the HW structure
  117  *  @mbx_id: id of mailbox to check
  118  *
  119  *  returns SUCCESS if the Status bit was found or else ERR_MBX
  120  **/
  121 s32 e1000_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
  122 {
  123         struct e1000_mbx_info *mbx = &hw->mbx;
  124         s32 ret_val = -E1000_ERR_MBX;
  125 
  126         DEBUGFUNC("e1000_check_for_msg");
  127 
  128         if (mbx->ops.check_for_msg)
  129                 ret_val = mbx->ops.check_for_msg(hw, mbx_id);
  130 
  131         return ret_val;
  132 }
  133 
  134 /**
  135  *  e1000_check_for_ack - checks to see if someone sent us ACK
  136  *  @hw: pointer to the HW structure
  137  *  @mbx_id: id of mailbox to check
  138  *
  139  *  returns SUCCESS if the Status bit was found or else ERR_MBX
  140  **/
  141 s32 e1000_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
  142 {
  143         struct e1000_mbx_info *mbx = &hw->mbx;
  144         s32 ret_val = -E1000_ERR_MBX;
  145 
  146         DEBUGFUNC("e1000_check_for_ack");
  147 
  148         if (mbx->ops.check_for_ack)
  149                 ret_val = mbx->ops.check_for_ack(hw, mbx_id);
  150 
  151         return ret_val;
  152 }
  153 
  154 /**
  155  *  e1000_check_for_rst - checks to see if other side has reset
  156  *  @hw: pointer to the HW structure
  157  *  @mbx_id: id of mailbox to check
  158  *
  159  *  returns SUCCESS if the Status bit was found or else ERR_MBX
  160  **/
  161 s32 e1000_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
  162 {
  163         struct e1000_mbx_info *mbx = &hw->mbx;
  164         s32 ret_val = -E1000_ERR_MBX;
  165 
  166         DEBUGFUNC("e1000_check_for_rst");
  167 
  168         if (mbx->ops.check_for_rst)
  169                 ret_val = mbx->ops.check_for_rst(hw, mbx_id);
  170 
  171         return ret_val;
  172 }
  173 
  174 /**
  175  *  e1000_poll_for_msg - Wait for message notification
  176  *  @hw: pointer to the HW structure
  177  *  @mbx_id: id of mailbox to write
  178  *
  179  *  returns SUCCESS if it successfully received a message notification
  180  **/
  181 static s32 e1000_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
  182 {
  183         struct e1000_mbx_info *mbx = &hw->mbx;
  184         int countdown = mbx->timeout;
  185 
  186         DEBUGFUNC("e1000_poll_for_msg");
  187 
  188         if (!countdown || !mbx->ops.check_for_msg)
  189                 goto out;
  190 
  191         while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
  192                 countdown--;
  193                 if (!countdown)
  194                         break;
  195                 usec_delay(mbx->usec_delay);
  196         }
  197 
  198         /* if we failed, all future posted messages fail until reset */
  199         if (!countdown)
  200                 mbx->timeout = 0;
  201 out:
  202         return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
  203 }
  204 
  205 /**
  206  *  e1000_poll_for_ack - Wait for message acknowledgement
  207  *  @hw: pointer to the HW structure
  208  *  @mbx_id: id of mailbox to write
  209  *
  210  *  returns SUCCESS if it successfully received a message acknowledgement
  211  **/
  212 static s32 e1000_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
  213 {
  214         struct e1000_mbx_info *mbx = &hw->mbx;
  215         int countdown = mbx->timeout;
  216 
  217         DEBUGFUNC("e1000_poll_for_ack");
  218 
  219         if (!countdown || !mbx->ops.check_for_ack)
  220                 goto out;
  221 
  222         while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
  223                 countdown--;
  224                 if (!countdown)
  225                         break;
  226                 usec_delay(mbx->usec_delay);
  227         }
  228 
  229         /* if we failed, all future posted messages fail until reset */
  230         if (!countdown)
  231                 mbx->timeout = 0;
  232 out:
  233         return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
  234 }
  235 
  236 /**
  237  *  e1000_read_posted_mbx - Wait for message notification and receive message
  238  *  @hw: pointer to the HW structure
  239  *  @msg: The message buffer
  240  *  @size: Length of buffer
  241  *  @mbx_id: id of mailbox to write
  242  *
  243  *  returns SUCCESS if it successfully received a message notification and
  244  *  copied it into the receive buffer.
  245  **/
  246 s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
  247 {
  248         struct e1000_mbx_info *mbx = &hw->mbx;
  249         s32 ret_val = -E1000_ERR_MBX;
  250 
  251         DEBUGFUNC("e1000_read_posted_mbx");
  252 
  253         if (!mbx->ops.read)
  254                 goto out;
  255 
  256         ret_val = e1000_poll_for_msg(hw, mbx_id);
  257 
  258         /* if ack received read message, otherwise we timed out */
  259         if (!ret_val)
  260                 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
  261 out:
  262         return ret_val;
  263 }
  264 
  265 /**
  266  *  e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
  267  *  @hw: pointer to the HW structure
  268  *  @msg: The message buffer
  269  *  @size: Length of buffer
  270  *  @mbx_id: id of mailbox to write
  271  *
  272  *  returns SUCCESS if it successfully copied message into the buffer and
  273  *  received an ack to that message within delay * timeout period
  274  **/
  275 s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
  276 {
  277         struct e1000_mbx_info *mbx = &hw->mbx;
  278         s32 ret_val = -E1000_ERR_MBX;
  279 
  280         DEBUGFUNC("e1000_write_posted_mbx");
  281 
  282         /* exit if either we can't write or there isn't a defined timeout */
  283         if (!mbx->ops.write || !mbx->timeout)
  284                 goto out;
  285 
  286         /* send msg */
  287         ret_val = mbx->ops.write(hw, msg, size, mbx_id);
  288 
  289         /* if msg sent wait until we receive an ack */
  290         if (!ret_val)
  291                 ret_val = e1000_poll_for_ack(hw, mbx_id);
  292 out:
  293         return ret_val;
  294 }
  295 
  296 /**
  297  *  e1000_init_mbx_ops_generic - Initialize mbx function pointers
  298  *  @hw: pointer to the HW structure
  299  *
  300  *  Sets the function pointers to no-op functions
  301  **/
  302 void e1000_init_mbx_ops_generic(struct e1000_hw *hw)
  303 {
  304         struct e1000_mbx_info *mbx = &hw->mbx;
  305         mbx->ops.init_params = e1000_null_ops_generic;
  306         mbx->ops.read = e1000_null_mbx_transact;
  307         mbx->ops.write = e1000_null_mbx_transact;
  308         mbx->ops.check_for_msg = e1000_null_mbx_check_for_flag;
  309         mbx->ops.check_for_ack = e1000_null_mbx_check_for_flag;
  310         mbx->ops.check_for_rst = e1000_null_mbx_check_for_flag;
  311         mbx->ops.read_posted = e1000_read_posted_mbx;
  312         mbx->ops.write_posted = e1000_write_posted_mbx;
  313 }
  314 
  315 /**
  316  *  e1000_read_v2p_mailbox - read v2p mailbox
  317  *  @hw: pointer to the HW structure
  318  *
  319  *  This function is used to read the v2p mailbox without losing the read to
  320  *  clear status bits.
  321  **/
  322 static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)
  323 {
  324         u32 v2p_mailbox = E1000_READ_REG(hw, E1000_V2PMAILBOX(0));
  325 
  326         v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
  327         hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
  328 
  329         return v2p_mailbox;
  330 }
  331 
  332 /**
  333  *  e1000_check_for_bit_vf - Determine if a status bit was set
  334  *  @hw: pointer to the HW structure
  335  *  @mask: bitmask for bits to be tested and cleared
  336  *
  337  *  This function is used to check for the read to clear bits within
  338  *  the V2P mailbox.
  339  **/
  340 static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
  341 {
  342         u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);
  343         s32 ret_val = -E1000_ERR_MBX;
  344 
  345         if (v2p_mailbox & mask)
  346                 ret_val = E1000_SUCCESS;
  347 
  348         hw->dev_spec.vf.v2p_mailbox &= ~mask;
  349 
  350         return ret_val;
  351 }
  352 
  353 /**
  354  *  e1000_check_for_msg_vf - checks to see if the PF has sent mail
  355  *  @hw: pointer to the HW structure
  356  *  @mbx_id: id of mailbox to check
  357  *
  358  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
  359  **/
  360 static s32 e1000_check_for_msg_vf(struct e1000_hw *hw,
  361                                   u16 E1000_UNUSEDARG mbx_id)
  362 {
  363         s32 ret_val = -E1000_ERR_MBX;
  364 
  365         DEBUGFUNC("e1000_check_for_msg_vf");
  366 
  367         if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
  368                 ret_val = E1000_SUCCESS;
  369                 hw->mbx.stats.reqs++;
  370         }
  371 
  372         return ret_val;
  373 }
  374 
  375 /**
  376  *  e1000_check_for_ack_vf - checks to see if the PF has ACK'd
  377  *  @hw: pointer to the HW structure
  378  *  @mbx_id: id of mailbox to check
  379  *
  380  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
  381  **/
  382 static s32 e1000_check_for_ack_vf(struct e1000_hw *hw,
  383                                   u16 E1000_UNUSEDARG mbx_id)
  384 {
  385         s32 ret_val = -E1000_ERR_MBX;
  386 
  387         DEBUGFUNC("e1000_check_for_ack_vf");
  388 
  389         if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
  390                 ret_val = E1000_SUCCESS;
  391                 hw->mbx.stats.acks++;
  392         }
  393 
  394         return ret_val;
  395 }
  396 
  397 /**
  398  *  e1000_check_for_rst_vf - checks to see if the PF has reset
  399  *  @hw: pointer to the HW structure
  400  *  @mbx_id: id of mailbox to check
  401  *
  402  *  returns TRUE if the PF has set the reset done bit or else FALSE
  403  **/
  404 static s32 e1000_check_for_rst_vf(struct e1000_hw *hw,
  405                                   u16 E1000_UNUSEDARG mbx_id)
  406 {
  407         s32 ret_val = -E1000_ERR_MBX;
  408 
  409         DEBUGFUNC("e1000_check_for_rst_vf");
  410 
  411         if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
  412                                          E1000_V2PMAILBOX_RSTI))) {
  413                 ret_val = E1000_SUCCESS;
  414                 hw->mbx.stats.rsts++;
  415         }
  416 
  417         return ret_val;
  418 }
  419 
  420 /**
  421  *  e1000_obtain_mbx_lock_vf - obtain mailbox lock
  422  *  @hw: pointer to the HW structure
  423  *
  424  *  return SUCCESS if we obtained the mailbox lock
  425  **/
  426 static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
  427 {
  428         s32 ret_val = -E1000_ERR_MBX;
  429 
  430         DEBUGFUNC("e1000_obtain_mbx_lock_vf");
  431 
  432         /* Take ownership of the buffer */
  433         E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
  434 
  435         /* reserve mailbox for vf use */
  436         if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
  437                 ret_val = E1000_SUCCESS;
  438 
  439         return ret_val;
  440 }
  441 
  442 /**
  443  *  e1000_write_mbx_vf - Write a message to the mailbox
  444  *  @hw: pointer to the HW structure
  445  *  @msg: The message buffer
  446  *  @size: Length of buffer
  447  *  @mbx_id: id of mailbox to write
  448  *
  449  *  returns SUCCESS if it successfully copied message into the buffer
  450  **/
  451 static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
  452                               u16 E1000_UNUSEDARG mbx_id)
  453 {
  454         s32 ret_val;
  455         u16 i;
  456 
  457 
  458         DEBUGFUNC("e1000_write_mbx_vf");
  459 
  460         /* lock the mailbox to prevent pf/vf race condition */
  461         ret_val = e1000_obtain_mbx_lock_vf(hw);
  462         if (ret_val)
  463                 goto out_no_write;
  464 
  465         /* flush msg and acks as we are overwriting the message buffer */
  466         e1000_check_for_msg_vf(hw, 0);
  467         e1000_check_for_ack_vf(hw, 0);
  468 
  469         /* copy the caller specified message to the mailbox memory buffer */
  470         for (i = 0; i < size; i++)
  471                 E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(0), i, msg[i]);
  472 
  473         /* update stats */
  474         hw->mbx.stats.msgs_tx++;
  475 
  476         /* Drop VFU and interrupt the PF to tell it a message has been sent */
  477         E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
  478 
  479 out_no_write:
  480         return ret_val;
  481 }
  482 
  483 /**
  484  *  e1000_read_mbx_vf - Reads a message from the inbox intended for vf
  485  *  @hw: pointer to the HW structure
  486  *  @msg: The message buffer
  487  *  @size: Length of buffer
  488  *  @mbx_id: id of mailbox to read
  489  *
  490  *  returns SUCCESS if it successfuly read message from buffer
  491  **/
  492 static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
  493                              u16 E1000_UNUSEDARG mbx_id)
  494 {
  495         s32 ret_val = E1000_SUCCESS;
  496         u16 i;
  497 
  498         DEBUGFUNC("e1000_read_mbx_vf");
  499 
  500         /* lock the mailbox to prevent pf/vf race condition */
  501         ret_val = e1000_obtain_mbx_lock_vf(hw);
  502         if (ret_val)
  503                 goto out_no_read;
  504 
  505         /* copy the message from the mailbox memory buffer */
  506         for (i = 0; i < size; i++)
  507                 msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(0), i);
  508 
  509         /* Acknowledge receipt and release mailbox, then we're done */
  510         E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
  511 
  512         /* update stats */
  513         hw->mbx.stats.msgs_rx++;
  514 
  515 out_no_read:
  516         return ret_val;
  517 }
  518 
  519 /**
  520  *  e1000_init_mbx_params_vf - set initial values for vf mailbox
  521  *  @hw: pointer to the HW structure
  522  *
  523  *  Initializes the hw->mbx struct to correct values for vf mailbox
  524  */
  525 s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)
  526 {
  527         struct e1000_mbx_info *mbx = &hw->mbx;
  528 
  529         /* start mailbox as timed out and let the reset_hw call set the timeout
  530          * value to begin communications */
  531         mbx->timeout = 0;
  532         mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
  533 
  534         mbx->size = E1000_VFMAILBOX_SIZE;
  535 
  536         mbx->ops.read = e1000_read_mbx_vf;
  537         mbx->ops.write = e1000_write_mbx_vf;
  538         mbx->ops.read_posted = e1000_read_posted_mbx;
  539         mbx->ops.write_posted = e1000_write_posted_mbx;
  540         mbx->ops.check_for_msg = e1000_check_for_msg_vf;
  541         mbx->ops.check_for_ack = e1000_check_for_ack_vf;
  542         mbx->ops.check_for_rst = e1000_check_for_rst_vf;
  543 
  544         mbx->stats.msgs_tx = 0;
  545         mbx->stats.msgs_rx = 0;
  546         mbx->stats.reqs = 0;
  547         mbx->stats.acks = 0;
  548         mbx->stats.rsts = 0;
  549 
  550         return E1000_SUCCESS;
  551 }
  552 
  553 static s32 e1000_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
  554 {
  555         u32 mbvficr = E1000_READ_REG(hw, E1000_MBVFICR);
  556         s32 ret_val = -E1000_ERR_MBX;
  557 
  558         if (mbvficr & mask) {
  559                 ret_val = E1000_SUCCESS;
  560                 E1000_WRITE_REG(hw, E1000_MBVFICR, mask);
  561         }
  562 
  563         return ret_val;
  564 }
  565 
  566 /**
  567  *  e1000_check_for_msg_pf - checks to see if the VF has sent mail
  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 e1000_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
  574 {
  575         s32 ret_val = -E1000_ERR_MBX;
  576 
  577         DEBUGFUNC("e1000_check_for_msg_pf");
  578 
  579         if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
  580                 ret_val = E1000_SUCCESS;
  581                 hw->mbx.stats.reqs++;
  582         }
  583 
  584         return ret_val;
  585 }
  586 
  587 /**
  588  *  e1000_check_for_ack_pf - checks to see if the VF has ACKed
  589  *  @hw: pointer to the HW structure
  590  *  @vf_number: the VF index
  591  *
  592  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
  593  **/
  594 static s32 e1000_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
  595 {
  596         s32 ret_val = -E1000_ERR_MBX;
  597 
  598         DEBUGFUNC("e1000_check_for_ack_pf");
  599 
  600         if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
  601                 ret_val = E1000_SUCCESS;
  602                 hw->mbx.stats.acks++;
  603         }
  604 
  605         return ret_val;
  606 }
  607 
  608 /**
  609  *  e1000_check_for_rst_pf - checks to see if the VF has reset
  610  *  @hw: pointer to the HW structure
  611  *  @vf_number: the VF index
  612  *
  613  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
  614  **/
  615 static s32 e1000_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
  616 {
  617         u32 vflre = E1000_READ_REG(hw, E1000_VFLRE);
  618         s32 ret_val = -E1000_ERR_MBX;
  619 
  620         DEBUGFUNC("e1000_check_for_rst_pf");
  621 
  622         if (vflre & (1 << vf_number)) {
  623                 ret_val = E1000_SUCCESS;
  624                 E1000_WRITE_REG(hw, E1000_VFLRE, (1 << vf_number));
  625                 hw->mbx.stats.rsts++;
  626         }
  627 
  628         return ret_val;
  629 }
  630 
  631 /**
  632  *  e1000_obtain_mbx_lock_pf - obtain mailbox lock
  633  *  @hw: pointer to the HW structure
  634  *  @vf_number: the VF index
  635  *
  636  *  return SUCCESS if we obtained the mailbox lock
  637  **/
  638 static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
  639 {
  640         s32 ret_val = -E1000_ERR_MBX;
  641         u32 p2v_mailbox;
  642 
  643         DEBUGFUNC("e1000_obtain_mbx_lock_pf");
  644 
  645         /* Take ownership of the buffer */
  646         E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
  647 
  648         /* reserve mailbox for vf use */
  649         p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
  650         if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
  651                 ret_val = E1000_SUCCESS;
  652 
  653         return ret_val;
  654 }
  655 
  656 /**
  657  *  e1000_write_mbx_pf - Places a message in the mailbox
  658  *  @hw: pointer to the HW structure
  659  *  @msg: The message buffer
  660  *  @size: Length of buffer
  661  *  @vf_number: the VF index
  662  *
  663  *  returns SUCCESS if it successfully copied message into the buffer
  664  **/
  665 static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
  666                               u16 vf_number)
  667 {
  668         s32 ret_val;
  669         u16 i;
  670 
  671         DEBUGFUNC("e1000_write_mbx_pf");
  672 
  673         /* lock the mailbox to prevent pf/vf race condition */
  674         ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
  675         if (ret_val)
  676                 goto out_no_write;
  677 
  678         /* flush msg and acks as we are overwriting the message buffer */
  679         e1000_check_for_msg_pf(hw, vf_number);
  680         e1000_check_for_ack_pf(hw, vf_number);
  681 
  682         /* copy the caller specified message to the mailbox memory buffer */
  683         for (i = 0; i < size; i++)
  684                 E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i, msg[i]);
  685 
  686         /* Interrupt VF to tell it a message has been sent and release buffer*/
  687         E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
  688 
  689         /* update stats */
  690         hw->mbx.stats.msgs_tx++;
  691 
  692 out_no_write:
  693         return ret_val;
  694 
  695 }
  696 
  697 /**
  698  *  e1000_read_mbx_pf - Read a message from the mailbox
  699  *  @hw: pointer to the HW structure
  700  *  @msg: The message buffer
  701  *  @size: Length of buffer
  702  *  @vf_number: the VF index
  703  *
  704  *  This function copies a message from the mailbox buffer to the caller's
  705  *  memory buffer.  The presumption is that the caller knows that there was
  706  *  a message due to a VF request so no polling for message is needed.
  707  **/
  708 static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
  709                              u16 vf_number)
  710 {
  711         s32 ret_val;
  712         u16 i;
  713 
  714         DEBUGFUNC("e1000_read_mbx_pf");
  715 
  716         /* lock the mailbox to prevent pf/vf race condition */
  717         ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
  718         if (ret_val)
  719                 goto out_no_read;
  720 
  721         /* copy the message to the mailbox memory buffer */
  722         for (i = 0; i < size; i++)
  723                 msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i);
  724 
  725         /* Acknowledge the message and release buffer */
  726         E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
  727 
  728         /* update stats */
  729         hw->mbx.stats.msgs_rx++;
  730 
  731 out_no_read:
  732         return ret_val;
  733 }
  734 
  735 /**
  736  *  e1000_init_mbx_params_pf - set initial values for pf mailbox
  737  *  @hw: pointer to the HW structure
  738  *
  739  *  Initializes the hw->mbx struct to correct values for pf mailbox
  740  */
  741 s32 e1000_init_mbx_params_pf(struct e1000_hw *hw)
  742 {
  743         struct e1000_mbx_info *mbx = &hw->mbx;
  744 
  745         switch (hw->mac.type) {
  746         case e1000_82576:
  747         case e1000_i350:
  748         case e1000_i354:
  749                 mbx->timeout = 0;
  750                 mbx->usec_delay = 0;
  751 
  752                 mbx->size = E1000_VFMAILBOX_SIZE;
  753 
  754                 mbx->ops.read = e1000_read_mbx_pf;
  755                 mbx->ops.write = e1000_write_mbx_pf;
  756                 mbx->ops.read_posted = e1000_read_posted_mbx;
  757                 mbx->ops.write_posted = e1000_write_posted_mbx;
  758                 mbx->ops.check_for_msg = e1000_check_for_msg_pf;
  759                 mbx->ops.check_for_ack = e1000_check_for_ack_pf;
  760                 mbx->ops.check_for_rst = e1000_check_for_rst_pf;
  761 
  762                 mbx->stats.msgs_tx = 0;
  763                 mbx->stats.msgs_rx = 0;
  764                 mbx->stats.reqs = 0;
  765                 mbx->stats.acks = 0;
  766                 mbx->stats.rsts = 0;
  767         default:
  768                 return E1000_SUCCESS;
  769         }
  770 }
  771 

Cache object: 3e2108f1c27f867610e705ffcfa05fc8


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