diff options
Diffstat (limited to 'drivers/net/igb/e1000_mbx.c')
-rw-r--r-- | drivers/net/igb/e1000_mbx.c | 246 |
1 files changed, 163 insertions, 83 deletions
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c index 74f2f11ac290..8750b4634603 100644 --- a/drivers/net/igb/e1000_mbx.c +++ b/drivers/net/igb/e1000_mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2011 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -28,7 +28,33 @@ #include "e1000_mbx.h" /** - * igb_read_mbx - Reads a message from the mailbox + * e1000_null_mbx_check_for_flag - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +static s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw, + u16 E1000_UNUSEDARG mbx_id) +{ + DEBUGFUNC("e1000_null_mbx_check_flag"); + + return E1000_SUCCESS; +} + +/** + * e1000_null_mbx_transact - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw, + u32 E1000_UNUSEDARG *msg, + u16 E1000_UNUSEDARG size, + u16 E1000_UNUSEDARG mbx_id) +{ + DEBUGFUNC("e1000_null_mbx_rw_msg"); + + return E1000_SUCCESS; +} + +/** + * e1000_read_mbx - Reads a message from the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer @@ -36,11 +62,13 @@ * * returns SUCCESS if it successfuly read message from buffer **/ -s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) +s32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; s32 ret_val = -E1000_ERR_MBX; + DEBUGFUNC("e1000_read_mbx"); + /* limit read to size of mailbox */ if (size > mbx->size) size = mbx->size; @@ -52,7 +80,7 @@ s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) } /** - * igb_write_mbx - Write a message to the mailbox + * e1000_write_mbx - Write a message to the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer @@ -60,10 +88,12 @@ s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) * * returns SUCCESS if it successfully copied message into the buffer **/ -s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) +s32 e1000_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; - s32 ret_val = 0; + s32 ret_val = E1000_SUCCESS; + + DEBUGFUNC("e1000_write_mbx"); if (size > mbx->size) ret_val = -E1000_ERR_MBX; @@ -75,17 +105,19 @@ s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) } /** - * igb_check_for_msg - checks to see if someone sent us mail + * e1000_check_for_msg - checks to see if someone sent us mail * @hw: pointer to the HW structure * @mbx_id: id of mailbox to check * * returns SUCCESS if the Status bit was found or else ERR_MBX **/ -s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id) +s32 e1000_check_for_msg(struct e1000_hw *hw, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; s32 ret_val = -E1000_ERR_MBX; + DEBUGFUNC("e1000_check_for_msg"); + if (mbx->ops.check_for_msg) ret_val = mbx->ops.check_for_msg(hw, mbx_id); @@ -93,17 +125,19 @@ s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id) } /** - * igb_check_for_ack - checks to see if someone sent us ACK + * e1000_check_for_ack - checks to see if someone sent us ACK * @hw: pointer to the HW structure * @mbx_id: id of mailbox to check * * returns SUCCESS if the Status bit was found or else ERR_MBX **/ -s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id) +s32 e1000_check_for_ack(struct e1000_hw *hw, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; s32 ret_val = -E1000_ERR_MBX; + DEBUGFUNC("e1000_check_for_ack"); + if (mbx->ops.check_for_ack) ret_val = mbx->ops.check_for_ack(hw, mbx_id); @@ -111,17 +145,19 @@ s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id) } /** - * igb_check_for_rst - checks to see if other side has reset + * e1000_check_for_rst - checks to see if other side has reset * @hw: pointer to the HW structure * @mbx_id: id of mailbox to check * * returns SUCCESS if the Status bit was found or else ERR_MBX **/ -s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id) +s32 e1000_check_for_rst(struct e1000_hw *hw, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; s32 ret_val = -E1000_ERR_MBX; + DEBUGFUNC("e1000_check_for_rst"); + if (mbx->ops.check_for_rst) ret_val = mbx->ops.check_for_rst(hw, mbx_id); @@ -129,17 +165,19 @@ s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id) } /** - * igb_poll_for_msg - Wait for message notification + * e1000_poll_for_msg - Wait for message notification * @hw: pointer to the HW structure * @mbx_id: id of mailbox to write * * returns SUCCESS if it successfully received a message notification **/ -static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id) +static s32 e1000_poll_for_msg(struct e1000_hw *hw, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; int countdown = mbx->timeout; + DEBUGFUNC("e1000_poll_for_msg"); + if (!countdown || !mbx->ops.check_for_msg) goto out; @@ -147,28 +185,30 @@ static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id) countdown--; if (!countdown) break; - udelay(mbx->usec_delay); + usec_delay(mbx->usec_delay); } /* if we failed, all future posted messages fail until reset */ if (!countdown) mbx->timeout = 0; out: - return countdown ? 0 : -E1000_ERR_MBX; + return countdown ? E1000_SUCCESS : -E1000_ERR_MBX; } /** - * igb_poll_for_ack - Wait for message acknowledgement + * e1000_poll_for_ack - Wait for message acknowledgement * @hw: pointer to the HW structure * @mbx_id: id of mailbox to write * * returns SUCCESS if it successfully received a message acknowledgement **/ -static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id) +static s32 e1000_poll_for_ack(struct e1000_hw *hw, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; int countdown = mbx->timeout; + DEBUGFUNC("e1000_poll_for_ack"); + if (!countdown || !mbx->ops.check_for_ack) goto out; @@ -176,18 +216,18 @@ static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id) countdown--; if (!countdown) break; - udelay(mbx->usec_delay); + usec_delay(mbx->usec_delay); } /* if we failed, all future posted messages fail until reset */ if (!countdown) mbx->timeout = 0; out: - return countdown ? 0 : -E1000_ERR_MBX; + return countdown ? E1000_SUCCESS : -E1000_ERR_MBX; } /** - * igb_read_posted_mbx - Wait for message notification and receive message + * e1000_read_posted_mbx - Wait for message notification and receive message * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer @@ -196,16 +236,19 @@ out: * returns SUCCESS if it successfully received a message notification and * copied it into the receive buffer. **/ -static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) +s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; s32 ret_val = -E1000_ERR_MBX; + DEBUGFUNC("e1000_read_posted_mbx"); + if (!mbx->ops.read) goto out; - ret_val = igb_poll_for_msg(hw, mbx_id); + ret_val = e1000_poll_for_msg(hw, mbx_id); + /* if ack received read message, otherwise we timed out */ if (!ret_val) ret_val = mbx->ops.read(hw, msg, size, mbx_id); out: @@ -213,7 +256,7 @@ out: } /** - * igb_write_posted_mbx - Write a message to the mailbox, wait for ack + * e1000_write_posted_mbx - Write a message to the mailbox, wait for ack * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer @@ -222,11 +265,13 @@ out: * returns SUCCESS if it successfully copied message into the buffer and * received an ack to that message within delay * timeout period **/ -static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) +s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct e1000_mbx_info *mbx = &hw->mbx; s32 ret_val = -E1000_ERR_MBX; + DEBUGFUNC("e1000_write_posted_mbx"); + /* exit if either we can't write or there isn't a defined timeout */ if (!mbx->ops.write || !mbx->timeout) goto out; @@ -236,37 +281,58 @@ static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx /* if msg sent wait until we receive an ack */ if (!ret_val) - ret_val = igb_poll_for_ack(hw, mbx_id); + ret_val = e1000_poll_for_ack(hw, mbx_id); out: return ret_val; } -static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask) +/** + * e1000_init_mbx_ops_generic - Initialize mbx function pointers + * @hw: pointer to the HW structure + * + * Sets the function pointers to no-op functions + **/ +void e1000_init_mbx_ops_generic(struct e1000_hw *hw) { - u32 mbvficr = rd32(E1000_MBVFICR); + struct e1000_mbx_info *mbx = &hw->mbx; + mbx->ops.init_params = e1000_null_ops_generic; + mbx->ops.read = e1000_null_mbx_transact; + mbx->ops.write = e1000_null_mbx_transact; + mbx->ops.check_for_msg = e1000_null_mbx_check_for_flag; + mbx->ops.check_for_ack = e1000_null_mbx_check_for_flag; + mbx->ops.check_for_rst = e1000_null_mbx_check_for_flag; + mbx->ops.read_posted = e1000_read_posted_mbx; + mbx->ops.write_posted = e1000_write_posted_mbx; +} + +static s32 e1000_check_for_bit_pf(struct e1000_hw *hw, u32 mask) +{ + u32 mbvficr = E1000_READ_REG(hw, E1000_MBVFICR); s32 ret_val = -E1000_ERR_MBX; if (mbvficr & mask) { - ret_val = 0; - wr32(E1000_MBVFICR, mask); + ret_val = E1000_SUCCESS; + E1000_WRITE_REG(hw, E1000_MBVFICR, mask); } return ret_val; } /** - * igb_check_for_msg_pf - checks to see if the VF has sent mail + * e1000_check_for_msg_pf - checks to see if the VF has sent mail * @hw: pointer to the HW structure * @vf_number: the VF index * * returns SUCCESS if the VF has set the Status bit or else ERR_MBX **/ -static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number) +static s32 e1000_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number) { s32 ret_val = -E1000_ERR_MBX; - if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) { - ret_val = 0; + DEBUGFUNC("e1000_check_for_msg_pf"); + + if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) { + ret_val = E1000_SUCCESS; hw->mbx.stats.reqs++; } @@ -274,18 +340,20 @@ static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number) } /** - * igb_check_for_ack_pf - checks to see if the VF has ACKed + * e1000_check_for_ack_pf - checks to see if the VF has ACKed * @hw: pointer to the HW structure * @vf_number: the VF index * * returns SUCCESS if the VF has set the Status bit or else ERR_MBX **/ -static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number) +static s32 e1000_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number) { s32 ret_val = -E1000_ERR_MBX; - if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) { - ret_val = 0; + DEBUGFUNC("e1000_check_for_ack_pf"); + + if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) { + ret_val = E1000_SUCCESS; hw->mbx.stats.acks++; } @@ -293,20 +361,22 @@ static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number) } /** - * igb_check_for_rst_pf - checks to see if the VF has reset + * e1000_check_for_rst_pf - checks to see if the VF has reset * @hw: pointer to the HW structure * @vf_number: the VF index * * returns SUCCESS if the VF has set the Status bit or else ERR_MBX **/ -static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number) +static s32 e1000_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number) { - u32 vflre = rd32(E1000_VFLRE); + u32 vflre = E1000_READ_REG(hw, E1000_VFLRE); s32 ret_val = -E1000_ERR_MBX; + DEBUGFUNC("e1000_check_for_rst_pf"); + if (vflre & (1 << vf_number)) { - ret_val = 0; - wr32(E1000_VFLRE, (1 << vf_number)); + ret_val = E1000_SUCCESS; + E1000_WRITE_REG(hw, E1000_VFLRE, (1 << vf_number)); hw->mbx.stats.rsts++; } @@ -314,31 +384,32 @@ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number) } /** - * igb_obtain_mbx_lock_pf - obtain mailbox lock + * e1000_obtain_mbx_lock_pf - obtain mailbox lock * @hw: pointer to the HW structure * @vf_number: the VF index * * return SUCCESS if we obtained the mailbox lock **/ -static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number) +static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number) { s32 ret_val = -E1000_ERR_MBX; u32 p2v_mailbox; + DEBUGFUNC("e1000_obtain_mbx_lock_pf"); /* Take ownership of the buffer */ - wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU); + E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU); /* reserve mailbox for vf use */ - p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number)); + p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number)); if (p2v_mailbox & E1000_P2VMAILBOX_PFU) - ret_val = 0; + ret_val = E1000_SUCCESS; return ret_val; } /** - * igb_write_mbx_pf - Places a message in the mailbox + * e1000_write_mbx_pf - Places a message in the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer @@ -346,27 +417,29 @@ static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number) * * returns SUCCESS if it successfully copied message into the buffer **/ -static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, - u16 vf_number) +static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, + u16 vf_number) { s32 ret_val; u16 i; + DEBUGFUNC("e1000_write_mbx_pf"); + /* lock the mailbox to prevent pf/vf race condition */ - ret_val = igb_obtain_mbx_lock_pf(hw, vf_number); + ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number); if (ret_val) goto out_no_write; /* flush msg and acks as we are overwriting the message buffer */ - igb_check_for_msg_pf(hw, vf_number); - igb_check_for_ack_pf(hw, vf_number); + e1000_check_for_msg_pf(hw, vf_number); + e1000_check_for_ack_pf(hw, vf_number); /* copy the caller specified message to the mailbox memory buffer */ for (i = 0; i < size; i++) - array_wr32(E1000_VMBMEM(vf_number), i, msg[i]); + E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i, msg[i]); /* Interrupt VF to tell it a message has been sent and release buffer*/ - wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS); + E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS); /* update stats */ hw->mbx.stats.msgs_tx++; @@ -377,7 +450,7 @@ out_no_write: } /** - * igb_read_mbx_pf - Read a message from the mailbox + * e1000_read_mbx_pf - Read a message from the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer @@ -387,23 +460,25 @@ out_no_write: * memory buffer. The presumption is that the caller knows that there was * a message due to a VF request so no polling for message is needed. **/ -static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, - u16 vf_number) +static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, + u16 vf_number) { s32 ret_val; u16 i; + DEBUGFUNC("e1000_read_mbx_pf"); + /* lock the mailbox to prevent pf/vf race condition */ - ret_val = igb_obtain_mbx_lock_pf(hw, vf_number); + ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number); if (ret_val) goto out_no_read; /* copy the message to the mailbox memory buffer */ for (i = 0; i < size; i++) - msg[i] = array_rd32(E1000_VMBMEM(vf_number), i); + msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i); /* Acknowledge the message and release buffer */ - wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK); + E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK); /* update stats */ hw->mbx.stats.msgs_rx++; @@ -418,29 +493,34 @@ out_no_read: * * Initializes the hw->mbx struct to correct values for pf mailbox */ -s32 igb_init_mbx_params_pf(struct e1000_hw *hw) +s32 e1000_init_mbx_params_pf(struct e1000_hw *hw) { struct e1000_mbx_info *mbx = &hw->mbx; - mbx->timeout = 0; - mbx->usec_delay = 0; - - mbx->size = E1000_VFMAILBOX_SIZE; - - mbx->ops.read = igb_read_mbx_pf; - mbx->ops.write = igb_write_mbx_pf; - mbx->ops.read_posted = igb_read_posted_mbx; - mbx->ops.write_posted = igb_write_posted_mbx; - mbx->ops.check_for_msg = igb_check_for_msg_pf; - mbx->ops.check_for_ack = igb_check_for_ack_pf; - mbx->ops.check_for_rst = igb_check_for_rst_pf; - - mbx->stats.msgs_tx = 0; - mbx->stats.msgs_rx = 0; - mbx->stats.reqs = 0; - mbx->stats.acks = 0; - mbx->stats.rsts = 0; - - return 0; + switch (hw->mac.type) { + case e1000_82576: + case e1000_i350: + case e1000_i354: + mbx->timeout = 0; + mbx->usec_delay = 0; + + mbx->size = E1000_VFMAILBOX_SIZE; + + mbx->ops.read = e1000_read_mbx_pf; + mbx->ops.write = e1000_write_mbx_pf; + mbx->ops.read_posted = e1000_read_posted_mbx; + mbx->ops.write_posted = e1000_write_posted_mbx; + mbx->ops.check_for_msg = e1000_check_for_msg_pf; + mbx->ops.check_for_ack = e1000_check_for_ack_pf; + mbx->ops.check_for_rst = e1000_check_for_rst_pf; + + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; + default: + return E1000_SUCCESS; + } } |