ixgbe: Check whether FDIRCMD writes actually complete
Wait up to about 100 us for FDIRCMD writes to complete and return failure indications. Signed-off-by: Mark Rustad <mark.d.rustad@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
b5529ef5be
commit
d490d15877
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Intel 10 Gigabit PCI Express Linux driver
|
Intel 10 Gigabit PCI Express Linux driver
|
||||||
Copyright(c) 1999 - 2014 Intel Corporation.
|
Copyright(c) 1999 - 2015 Intel Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
under the terms and conditions of the GNU General Public License,
|
under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -1241,6 +1241,25 @@ mac_reset_top:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_fdir_check_cmd_complete - poll to check whether FDIRCMD is complete
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @fdircmd: current value of FDIRCMD register
|
||||||
|
*/
|
||||||
|
static s32 ixgbe_fdir_check_cmd_complete(struct ixgbe_hw *hw, u32 *fdircmd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
|
||||||
|
*fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD);
|
||||||
|
if (!(*fdircmd & IXGBE_FDIRCMD_CMD_MASK))
|
||||||
|
return 0;
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IXGBE_ERR_FDIR_CMD_INCOMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables.
|
* ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables.
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
|
@ -1249,6 +1268,8 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
|
u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
|
||||||
|
u32 fdircmd;
|
||||||
|
s32 err;
|
||||||
|
|
||||||
fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE;
|
fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE;
|
||||||
|
|
||||||
|
@ -1256,15 +1277,10 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
|
||||||
* Before starting reinitialization process,
|
* Before starting reinitialization process,
|
||||||
* FDIRCMD.CMD must be zero.
|
* FDIRCMD.CMD must be zero.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
|
err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd);
|
||||||
if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
|
if (err) {
|
||||||
IXGBE_FDIRCMD_CMD_MASK))
|
hw_dbg(hw, "Flow Director previous command did not complete, aborting table re-initialization.\n");
|
||||||
break;
|
return err;
|
||||||
udelay(10);
|
|
||||||
}
|
|
||||||
if (i >= IXGBE_FDIRCMD_CMD_POLL) {
|
|
||||||
hw_dbg(hw, "Flow Director previous command isn't complete, aborting table re-initialization.\n");
|
|
||||||
return IXGBE_ERR_FDIR_REINIT_FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
|
IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
|
||||||
|
@ -1754,6 +1770,7 @@ s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
|
||||||
u16 soft_id, u8 queue)
|
u16 soft_id, u8 queue)
|
||||||
{
|
{
|
||||||
u32 fdirport, fdirvlan, fdirhash, fdircmd;
|
u32 fdirport, fdirvlan, fdirhash, fdircmd;
|
||||||
|
s32 err;
|
||||||
|
|
||||||
/* currently IPv6 is not supported, must be programmed with 0 */
|
/* currently IPv6 is not supported, must be programmed with 0 */
|
||||||
IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0),
|
IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0),
|
||||||
|
@ -1802,6 +1819,11 @@ s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
|
||||||
fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT;
|
fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT;
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
|
IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
|
||||||
|
err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd);
|
||||||
|
if (err) {
|
||||||
|
hw_dbg(hw, "Flow Director command did not complete!\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1811,9 +1833,8 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
|
||||||
u16 soft_id)
|
u16 soft_id)
|
||||||
{
|
{
|
||||||
u32 fdirhash;
|
u32 fdirhash;
|
||||||
u32 fdircmd = 0;
|
u32 fdircmd;
|
||||||
u32 retry_count;
|
s32 err;
|
||||||
s32 err = 0;
|
|
||||||
|
|
||||||
/* configure FDIRHASH register */
|
/* configure FDIRHASH register */
|
||||||
fdirhash = input->formatted.bkt_hash;
|
fdirhash = input->formatted.bkt_hash;
|
||||||
|
@ -1826,18 +1847,12 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
|
||||||
/* Query if filter is present */
|
/* Query if filter is present */
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT);
|
IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT);
|
||||||
|
|
||||||
for (retry_count = 10; retry_count; retry_count--) {
|
err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd);
|
||||||
/* allow 10us for query to process */
|
if (err) {
|
||||||
udelay(10);
|
hw_dbg(hw, "Flow Director command did not complete!\n");
|
||||||
/* verify query completed successfully */
|
return err;
|
||||||
fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD);
|
|
||||||
if (!(fdircmd & IXGBE_FDIRCMD_CMD_MASK))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!retry_count)
|
|
||||||
err = IXGBE_ERR_FDIR_REINIT_FAILED;
|
|
||||||
|
|
||||||
/* if filter exists in hardware then remove it */
|
/* if filter exists in hardware then remove it */
|
||||||
if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) {
|
if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) {
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
|
IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
|
||||||
|
@ -1846,7 +1861,7 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
|
||||||
IXGBE_FDIRCMD_CMD_REMOVE_FLOW);
|
IXGBE_FDIRCMD_CMD_REMOVE_FLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3460,6 +3460,7 @@ struct ixgbe_info {
|
||||||
#define IXGBE_ERR_PBA_SECTION -31
|
#define IXGBE_ERR_PBA_SECTION -31
|
||||||
#define IXGBE_ERR_INVALID_ARGUMENT -32
|
#define IXGBE_ERR_INVALID_ARGUMENT -32
|
||||||
#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33
|
#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33
|
||||||
|
#define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38
|
||||||
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
|
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
|
||||||
|
|
||||||
#define IXGBE_KRM_PORT_CAR_GEN_CTRL(P) ((P) ? 0x8010 : 0x4010)
|
#define IXGBE_KRM_PORT_CAR_GEN_CTRL(P) ((P) ? 0x8010 : 0x4010)
|
||||||
|
|
Loading…
Reference in New Issue