diff options
| -rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c | 63 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 1 | 
2 files changed, 40 insertions, 24 deletions
| diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index 08fcf57a22ec..d91044297062 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -1,7 +1,7 @@  /*******************************************************************************    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    under the terms and conditions of the GNU General Public License, @@ -1242,6 +1242,25 @@ mac_reset_top:  }  /** + * 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.   *  @hw: pointer to hardware structure   **/ @@ -1249,6 +1268,8 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)  {  	int i;  	u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL); +	u32 fdircmd; +	s32 err;  	fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE; @@ -1256,15 +1277,10 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)  	 * Before starting reinitialization process,  	 * FDIRCMD.CMD must be zero.  	 */ -	for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) { -		if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) & -		      IXGBE_FDIRCMD_CMD_MASK)) -			break; -		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; +	err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd); +	if (err) { +		hw_dbg(hw, "Flow Director previous command did not complete, aborting table re-initialization.\n"); +		return err;  	}  	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)  {  	u32 fdirport, fdirvlan, fdirhash, fdircmd; +	s32 err;  	/* currently IPv6 is not supported, must be programmed with 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;  	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;  } @@ -1811,9 +1833,8 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,  					  u16 soft_id)  {  	u32 fdirhash; -	u32 fdircmd = 0; -	u32 retry_count; -	s32 err = 0; +	u32 fdircmd; +	s32 err;  	/* configure FDIRHASH register */  	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 */  	IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT); -	for (retry_count = 10; retry_count; retry_count--) { -		/* allow 10us for query to process */ -		udelay(10); -		/* verify query completed successfully */ -		fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD); -		if (!(fdircmd & IXGBE_FDIRCMD_CMD_MASK)) -			break; +	err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd); +	if (err) { +		hw_dbg(hw, "Flow Director command did not complete!\n"); +		return err;  	} -	if (!retry_count) -		err = IXGBE_ERR_FDIR_REINIT_FAILED; -  	/* if filter exists in hardware then remove it */  	if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) {  		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);  	} -	return err; +	return 0;  }  /** diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 4615a949381d..938a4102adf5 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -3460,6 +3460,7 @@ struct ixgbe_info {  #define IXGBE_ERR_PBA_SECTION                   -31  #define IXGBE_ERR_INVALID_ARGUMENT              -32  #define IXGBE_ERR_HOST_INTERFACE_COMMAND        -33 +#define IXGBE_ERR_FDIR_CMD_INCOMPLETE		-38  #define IXGBE_NOT_IMPLEMENTED                   0x7FFFFFFF  #define IXGBE_KRM_PORT_CAR_GEN_CTRL(P)	((P) ? 0x8010 : 0x4010) | 
