提交 6a11e52b 编写于 作者: T Tony Nguyen 提交者: Jeff Kirsher

ixgbevf: Add range checking for setting MTU

Currently when setting the VF's MTU, the PF can return a NACK but this
isn't passed on to the VF.  Propagate the results from the PF to the VF
so errors can be reported.

In ixgbevf_change_mtu, return an error and reject the change.

For ixgbevf_configure_rx, log the error for debugging purposes since
the function is buried in a series of Rx config routines that are void.
Signed-off-by: NTony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: NEmil Tantilov <emil.s.tantilov@intel.com>
Tested-by: NAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
上级 6e469ed0
...@@ -1802,16 +1802,19 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter, ...@@ -1802,16 +1802,19 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter,
**/ **/
static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter) static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter)
{ {
int i;
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int i, ret;
ixgbevf_setup_psrtype(adapter); ixgbevf_setup_psrtype(adapter);
if (hw->mac.type >= ixgbe_mac_X550_vf) if (hw->mac.type >= ixgbe_mac_X550_vf)
ixgbevf_setup_vfmrqc(adapter); ixgbevf_setup_vfmrqc(adapter);
/* notify the PF of our intent to use this size of frame */ /* notify the PF of our intent to use this size of frame */
hw->mac.ops.set_rlpml(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN); ret = hw->mac.ops.set_rlpml(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
if (ret)
dev_err(&adapter->pdev->dev,
"Failed to set MTU at %d\n", netdev->mtu);
/* Setup the HW Rx Head and Tail Descriptor Pointers and /* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring * the Base and Length of the Rx Descriptor Ring
...@@ -3737,6 +3740,7 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -3737,6 +3740,7 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE; int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE;
int ret;
switch (adapter->hw.api_version) { switch (adapter->hw.api_version) {
case ixgbe_mbox_api_11: case ixgbe_mbox_api_11:
...@@ -3753,14 +3757,17 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -3753,14 +3757,17 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
if ((new_mtu < 68) || (max_frame > max_possible_frame)) if ((new_mtu < 68) || (max_frame > max_possible_frame))
return -EINVAL; return -EINVAL;
/* notify the PF of our intent to use this size of frame */
ret = hw->mac.ops.set_rlpml(hw, max_frame);
if (ret)
return -EINVAL;
hw_dbg(hw, "changing MTU from %d to %d\n", hw_dbg(hw, "changing MTU from %d to %d\n",
netdev->mtu, new_mtu); netdev->mtu, new_mtu);
/* must set new MTU before calling down or up */ /* must set new MTU before calling down or up */
netdev->mtu = new_mtu; netdev->mtu = new_mtu;
/* notify the PF of our intent to use this size of frame */
hw->mac.ops.set_rlpml(hw, max_frame);
return 0; return 0;
} }
......
...@@ -33,6 +33,18 @@ ...@@ -33,6 +33,18 @@
*/ */
#define IXGBE_HV_RESET_OFFSET 0x201 #define IXGBE_HV_RESET_OFFSET 0x201
static inline s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg,
u32 *retmsg, u16 size)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
s32 retval = mbx->ops.write_posted(hw, msg, size);
if (retval)
return retval;
return mbx->ops.read_posted(hw, retmsg, size);
}
/** /**
* ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx * ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -470,17 +482,6 @@ static s32 ixgbevf_hv_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, ...@@ -470,17 +482,6 @@ static s32 ixgbevf_hv_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw,
u32 *msg, u16 size)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
u32 retmsg[IXGBE_VFMAILBOX_SIZE];
s32 retval = mbx->ops.write_posted(hw, msg, size);
if (!retval)
mbx->ops.read_posted(hw, retmsg, size);
}
/** /**
* ixgbevf_update_mc_addr_list_vf - Update Multicast addresses * ixgbevf_update_mc_addr_list_vf - Update Multicast addresses
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
...@@ -521,7 +522,7 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw, ...@@ -521,7 +522,7 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr); vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr);
} }
ixgbevf_write_msg_read_ack(hw, msgbuf, IXGBE_VFMAILBOX_SIZE); ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, IXGBE_VFMAILBOX_SIZE);
return 0; return 0;
} }
...@@ -799,13 +800,22 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw, ...@@ -799,13 +800,22 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
* @max_size: value to assign to max frame size * @max_size: value to assign to max frame size
**/ **/
static void ixgbevf_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size) static s32 ixgbevf_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
{ {
u32 msgbuf[2]; u32 msgbuf[2];
s32 ret_val;
msgbuf[0] = IXGBE_VF_SET_LPE; msgbuf[0] = IXGBE_VF_SET_LPE;
msgbuf[1] = max_size; msgbuf[1] = max_size;
ixgbevf_write_msg_read_ack(hw, msgbuf, 2);
ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
if (ret_val)
return ret_val;
if ((msgbuf[0] & IXGBE_VF_SET_LPE) &&
(msgbuf[0] & IXGBE_VT_MSGTYPE_NACK))
return IXGBE_ERR_MBX;
return 0;
} }
/** /**
...@@ -814,7 +824,7 @@ static void ixgbevf_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size) ...@@ -814,7 +824,7 @@ static void ixgbevf_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
* @max_size: value to assign to max frame size * @max_size: value to assign to max frame size
* Hyper-V variant. * Hyper-V variant.
**/ **/
static void ixgbevf_hv_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size) static s32 ixgbevf_hv_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
{ {
u32 reg; u32 reg;
...@@ -825,6 +835,8 @@ static void ixgbevf_hv_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size) ...@@ -825,6 +835,8 @@ static void ixgbevf_hv_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
/* CRC == 4 */ /* CRC == 4 */
reg |= ((max_size + 4) | IXGBE_RXDCTL_RLPML_EN); reg |= ((max_size + 4) | IXGBE_RXDCTL_RLPML_EN);
IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(0), reg); IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(0), reg);
return 0;
} }
/** /**
......
...@@ -69,7 +69,7 @@ struct ixgbe_mac_operations { ...@@ -69,7 +69,7 @@ struct ixgbe_mac_operations {
s32 (*disable_mc)(struct ixgbe_hw *); s32 (*disable_mc)(struct ixgbe_hw *);
s32 (*clear_vfta)(struct ixgbe_hw *); s32 (*clear_vfta)(struct ixgbe_hw *);
s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool); s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
void (*set_rlpml)(struct ixgbe_hw *, u16); s32 (*set_rlpml)(struct ixgbe_hw *, u16);
}; };
enum ixgbe_mac_type { enum ixgbe_mac_type {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册