Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 2007 - 2018 Intel Corporation. */
0003 
0004 #include "e1000_mbx.h"
0005 
0006 /**
0007  *  igb_read_mbx - Reads a message from the mailbox
0008  *  @hw: pointer to the HW structure
0009  *  @msg: The message buffer
0010  *  @size: Length of buffer
0011  *  @mbx_id: id of mailbox to read
0012  *  @unlock: skip locking or not
0013  *
0014  *  returns SUCCESS if it successfully read message from buffer
0015  **/
0016 s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id,
0017          bool unlock)
0018 {
0019     struct e1000_mbx_info *mbx = &hw->mbx;
0020     s32 ret_val = -E1000_ERR_MBX;
0021 
0022     /* limit read to size of mailbox */
0023     if (size > mbx->size)
0024         size = mbx->size;
0025 
0026     if (mbx->ops.read)
0027         ret_val = mbx->ops.read(hw, msg, size, mbx_id, unlock);
0028 
0029     return ret_val;
0030 }
0031 
0032 /**
0033  *  igb_write_mbx - Write a message to the mailbox
0034  *  @hw: pointer to the HW structure
0035  *  @msg: The message buffer
0036  *  @size: Length of buffer
0037  *  @mbx_id: id of mailbox to write
0038  *
0039  *  returns SUCCESS if it successfully copied message into the buffer
0040  **/
0041 s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
0042 {
0043     struct e1000_mbx_info *mbx = &hw->mbx;
0044     s32 ret_val = 0;
0045 
0046     if (size > mbx->size)
0047         ret_val = -E1000_ERR_MBX;
0048 
0049     else if (mbx->ops.write)
0050         ret_val = mbx->ops.write(hw, msg, size, mbx_id);
0051 
0052     return ret_val;
0053 }
0054 
0055 /**
0056  *  igb_check_for_msg - checks to see if someone sent us mail
0057  *  @hw: pointer to the HW structure
0058  *  @mbx_id: id of mailbox to check
0059  *
0060  *  returns SUCCESS if the Status bit was found or else ERR_MBX
0061  **/
0062 s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
0063 {
0064     struct e1000_mbx_info *mbx = &hw->mbx;
0065     s32 ret_val = -E1000_ERR_MBX;
0066 
0067     if (mbx->ops.check_for_msg)
0068         ret_val = mbx->ops.check_for_msg(hw, mbx_id);
0069 
0070     return ret_val;
0071 }
0072 
0073 /**
0074  *  igb_check_for_ack - checks to see if someone sent us ACK
0075  *  @hw: pointer to the HW structure
0076  *  @mbx_id: id of mailbox to check
0077  *
0078  *  returns SUCCESS if the Status bit was found or else ERR_MBX
0079  **/
0080 s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
0081 {
0082     struct e1000_mbx_info *mbx = &hw->mbx;
0083     s32 ret_val = -E1000_ERR_MBX;
0084 
0085     if (mbx->ops.check_for_ack)
0086         ret_val = mbx->ops.check_for_ack(hw, mbx_id);
0087 
0088     return ret_val;
0089 }
0090 
0091 /**
0092  *  igb_check_for_rst - checks to see if other side has reset
0093  *  @hw: pointer to the HW structure
0094  *  @mbx_id: id of mailbox to check
0095  *
0096  *  returns SUCCESS if the Status bit was found or else ERR_MBX
0097  **/
0098 s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
0099 {
0100     struct e1000_mbx_info *mbx = &hw->mbx;
0101     s32 ret_val = -E1000_ERR_MBX;
0102 
0103     if (mbx->ops.check_for_rst)
0104         ret_val = mbx->ops.check_for_rst(hw, mbx_id);
0105 
0106     return ret_val;
0107 }
0108 
0109 /**
0110  *  igb_unlock_mbx - unlock the mailbox
0111  *  @hw: pointer to the HW structure
0112  *  @mbx_id: id of mailbox to check
0113  *
0114  *  returns SUCCESS if the mailbox was unlocked or else ERR_MBX
0115  **/
0116 s32 igb_unlock_mbx(struct e1000_hw *hw, u16 mbx_id)
0117 {
0118     struct e1000_mbx_info *mbx = &hw->mbx;
0119     s32 ret_val = -E1000_ERR_MBX;
0120 
0121     if (mbx->ops.unlock)
0122         ret_val = mbx->ops.unlock(hw, mbx_id);
0123 
0124     return ret_val;
0125 }
0126 
0127 /**
0128  *  igb_poll_for_msg - Wait for message notification
0129  *  @hw: pointer to the HW structure
0130  *  @mbx_id: id of mailbox to write
0131  *
0132  *  returns SUCCESS if it successfully received a message notification
0133  **/
0134 static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
0135 {
0136     struct e1000_mbx_info *mbx = &hw->mbx;
0137     int countdown = mbx->timeout;
0138 
0139     if (!countdown || !mbx->ops.check_for_msg)
0140         goto out;
0141 
0142     while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
0143         countdown--;
0144         if (!countdown)
0145             break;
0146         udelay(mbx->usec_delay);
0147     }
0148 
0149     /* if we failed, all future posted messages fail until reset */
0150     if (!countdown)
0151         mbx->timeout = 0;
0152 out:
0153     return countdown ? 0 : -E1000_ERR_MBX;
0154 }
0155 
0156 /**
0157  *  igb_poll_for_ack - Wait for message acknowledgement
0158  *  @hw: pointer to the HW structure
0159  *  @mbx_id: id of mailbox to write
0160  *
0161  *  returns SUCCESS if it successfully received a message acknowledgement
0162  **/
0163 static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
0164 {
0165     struct e1000_mbx_info *mbx = &hw->mbx;
0166     int countdown = mbx->timeout;
0167 
0168     if (!countdown || !mbx->ops.check_for_ack)
0169         goto out;
0170 
0171     while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
0172         countdown--;
0173         if (!countdown)
0174             break;
0175         udelay(mbx->usec_delay);
0176     }
0177 
0178     /* if we failed, all future posted messages fail until reset */
0179     if (!countdown)
0180         mbx->timeout = 0;
0181 out:
0182     return countdown ? 0 : -E1000_ERR_MBX;
0183 }
0184 
0185 /**
0186  *  igb_read_posted_mbx - Wait for message notification and receive message
0187  *  @hw: pointer to the HW structure
0188  *  @msg: The message buffer
0189  *  @size: Length of buffer
0190  *  @mbx_id: id of mailbox to write
0191  *
0192  *  returns SUCCESS if it successfully received a message notification and
0193  *  copied it into the receive buffer.
0194  **/
0195 static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
0196                    u16 mbx_id)
0197 {
0198     struct e1000_mbx_info *mbx = &hw->mbx;
0199     s32 ret_val = -E1000_ERR_MBX;
0200 
0201     if (!mbx->ops.read)
0202         goto out;
0203 
0204     ret_val = igb_poll_for_msg(hw, mbx_id);
0205 
0206     if (!ret_val)
0207         ret_val = mbx->ops.read(hw, msg, size, mbx_id, true);
0208 out:
0209     return ret_val;
0210 }
0211 
0212 /**
0213  *  igb_write_posted_mbx - Write a message to the mailbox, wait for ack
0214  *  @hw: pointer to the HW structure
0215  *  @msg: The message buffer
0216  *  @size: Length of buffer
0217  *  @mbx_id: id of mailbox to write
0218  *
0219  *  returns SUCCESS if it successfully copied message into the buffer and
0220  *  received an ack to that message within delay * timeout period
0221  **/
0222 static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size,
0223                 u16 mbx_id)
0224 {
0225     struct e1000_mbx_info *mbx = &hw->mbx;
0226     s32 ret_val = -E1000_ERR_MBX;
0227 
0228     /* exit if either we can't write or there isn't a defined timeout */
0229     if (!mbx->ops.write || !mbx->timeout)
0230         goto out;
0231 
0232     /* send msg */
0233     ret_val = mbx->ops.write(hw, msg, size, mbx_id);
0234 
0235     /* if msg sent wait until we receive an ack */
0236     if (!ret_val)
0237         ret_val = igb_poll_for_ack(hw, mbx_id);
0238 out:
0239     return ret_val;
0240 }
0241 
0242 static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
0243 {
0244     u32 mbvficr = rd32(E1000_MBVFICR);
0245     s32 ret_val = -E1000_ERR_MBX;
0246 
0247     if (mbvficr & mask) {
0248         ret_val = 0;
0249         wr32(E1000_MBVFICR, mask);
0250     }
0251 
0252     return ret_val;
0253 }
0254 
0255 /**
0256  *  igb_check_for_msg_pf - checks to see if the VF has sent mail
0257  *  @hw: pointer to the HW structure
0258  *  @vf_number: the VF index
0259  *
0260  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
0261  **/
0262 static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
0263 {
0264     s32 ret_val = -E1000_ERR_MBX;
0265 
0266     if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
0267         ret_val = 0;
0268         hw->mbx.stats.reqs++;
0269     }
0270 
0271     return ret_val;
0272 }
0273 
0274 /**
0275  *  igb_check_for_ack_pf - checks to see if the VF has ACKed
0276  *  @hw: pointer to the HW structure
0277  *  @vf_number: the VF index
0278  *
0279  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
0280  **/
0281 static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
0282 {
0283     s32 ret_val = -E1000_ERR_MBX;
0284 
0285     if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
0286         ret_val = 0;
0287         hw->mbx.stats.acks++;
0288     }
0289 
0290     return ret_val;
0291 }
0292 
0293 /**
0294  *  igb_check_for_rst_pf - checks to see if the VF has reset
0295  *  @hw: pointer to the HW structure
0296  *  @vf_number: the VF index
0297  *
0298  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
0299  **/
0300 static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
0301 {
0302     u32 vflre = rd32(E1000_VFLRE);
0303     s32 ret_val = -E1000_ERR_MBX;
0304 
0305     if (vflre & BIT(vf_number)) {
0306         ret_val = 0;
0307         wr32(E1000_VFLRE, BIT(vf_number));
0308         hw->mbx.stats.rsts++;
0309     }
0310 
0311     return ret_val;
0312 }
0313 
0314 /**
0315  *  igb_obtain_mbx_lock_pf - obtain mailbox lock
0316  *  @hw: pointer to the HW structure
0317  *  @vf_number: the VF index
0318  *
0319  *  return SUCCESS if we obtained the mailbox lock
0320  **/
0321 static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
0322 {
0323     s32 ret_val = -E1000_ERR_MBX;
0324     u32 p2v_mailbox;
0325     int count = 10;
0326 
0327     do {
0328         /* Take ownership of the buffer */
0329         wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
0330 
0331         /* reserve mailbox for vf use */
0332         p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
0333         if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
0334             ret_val = 0;
0335             break;
0336         }
0337         udelay(1000);
0338     } while (count-- > 0);
0339 
0340     return ret_val;
0341 }
0342 
0343 /**
0344  *  igb_release_mbx_lock_pf - release mailbox lock
0345  *  @hw: pointer to the HW structure
0346  *  @vf_number: the VF index
0347  *
0348  *  return SUCCESS if we released the mailbox lock
0349  **/
0350 static s32 igb_release_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
0351 {
0352     u32 p2v_mailbox;
0353 
0354     /* drop PF lock of mailbox, if set */
0355     p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
0356     if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
0357         wr32(E1000_P2VMAILBOX(vf_number),
0358              p2v_mailbox & ~E1000_P2VMAILBOX_PFU);
0359 
0360     return 0;
0361 }
0362 
0363 /**
0364  *  igb_write_mbx_pf - Places a message in the mailbox
0365  *  @hw: pointer to the HW structure
0366  *  @msg: The message buffer
0367  *  @size: Length of buffer
0368  *  @vf_number: the VF index
0369  *
0370  *  returns SUCCESS if it successfully copied message into the buffer
0371  **/
0372 static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
0373                 u16 vf_number)
0374 {
0375     s32 ret_val;
0376     u16 i;
0377 
0378     /* lock the mailbox to prevent pf/vf race condition */
0379     ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
0380     if (ret_val)
0381         goto out_no_write;
0382 
0383     /* flush msg and acks as we are overwriting the message buffer */
0384     igb_check_for_msg_pf(hw, vf_number);
0385     igb_check_for_ack_pf(hw, vf_number);
0386 
0387     /* copy the caller specified message to the mailbox memory buffer */
0388     for (i = 0; i < size; i++)
0389         array_wr32(E1000_VMBMEM(vf_number), i, msg[i]);
0390 
0391     /* Interrupt VF to tell it a message has been sent and release buffer*/
0392     wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
0393 
0394     /* update stats */
0395     hw->mbx.stats.msgs_tx++;
0396 
0397 out_no_write:
0398     return ret_val;
0399 
0400 }
0401 
0402 /**
0403  *  igb_read_mbx_pf - Read a message from the mailbox
0404  *  @hw: pointer to the HW structure
0405  *  @msg: The message buffer
0406  *  @size: Length of buffer
0407  *  @vf_number: the VF index
0408  *  @unlock: unlock the mailbox when done?
0409  *
0410  *  This function copies a message from the mailbox buffer to the caller's
0411  *  memory buffer.  The presumption is that the caller knows that there was
0412  *  a message due to a VF request so no polling for message is needed.
0413  **/
0414 static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
0415                u16 vf_number, bool unlock)
0416 {
0417     s32 ret_val;
0418     u16 i;
0419 
0420     /* lock the mailbox to prevent pf/vf race condition */
0421     ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
0422     if (ret_val)
0423         goto out_no_read;
0424 
0425     /* copy the message to the mailbox memory buffer */
0426     for (i = 0; i < size; i++)
0427         msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
0428 
0429     /* Acknowledge the message and release mailbox lock (or not) */
0430     if (unlock)
0431         wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
0432     else
0433         wr32(E1000_P2VMAILBOX(vf_number),
0434              E1000_P2VMAILBOX_ACK | E1000_P2VMAILBOX_PFU);
0435 
0436     /* update stats */
0437     hw->mbx.stats.msgs_rx++;
0438 
0439 out_no_read:
0440     return ret_val;
0441 }
0442 
0443 /**
0444  *  igb_init_mbx_params_pf - set initial values for pf mailbox
0445  *  @hw: pointer to the HW structure
0446  *
0447  *  Initializes the hw->mbx struct to correct values for pf mailbox
0448  */
0449 s32 igb_init_mbx_params_pf(struct e1000_hw *hw)
0450 {
0451     struct e1000_mbx_info *mbx = &hw->mbx;
0452 
0453     mbx->timeout = 0;
0454     mbx->usec_delay = 0;
0455 
0456     mbx->size = E1000_VFMAILBOX_SIZE;
0457 
0458     mbx->ops.read = igb_read_mbx_pf;
0459     mbx->ops.write = igb_write_mbx_pf;
0460     mbx->ops.read_posted = igb_read_posted_mbx;
0461     mbx->ops.write_posted = igb_write_posted_mbx;
0462     mbx->ops.check_for_msg = igb_check_for_msg_pf;
0463     mbx->ops.check_for_ack = igb_check_for_ack_pf;
0464     mbx->ops.check_for_rst = igb_check_for_rst_pf;
0465     mbx->ops.unlock = igb_release_mbx_lock_pf;
0466 
0467     mbx->stats.msgs_tx = 0;
0468     mbx->stats.msgs_rx = 0;
0469     mbx->stats.reqs = 0;
0470     mbx->stats.acks = 0;
0471     mbx->stats.rsts = 0;
0472 
0473     return 0;
0474 }
0475