Commit 19e1190a authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to i40e only.

Christopher Pau provides a patch to set pf_id based on device and
function numbers since NICs with ARI enabled can have function
numbers larger than 8.

Anjali provides 3 i40e patches to update hardware defines to keep
in sync with hardware updates.

Shannon provides the majority of i40e patches, with 7.  First patch
clears the admin queue head and tail registers during admin queue
shutdown. Then simplifies the admin queue head-tail-len setups to
use more virtual registers.  Provides several patches to cleanup
and fix driver load and reset procedures to make more robust.  Lastly,
provides an ethtool test for interrupts using the software interrupt.

Mitch provides some i40e patches which fixes up VF code in the PF
driver, specifically the number of vectors per VF are reported by the
hardware does not include vector 0, so we need to account for this
when checking.  In addition, cleans up debugging messages.

Kamil provides an i40e patch to fix the diagnostics test by restricting
the diagnostic test length.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f1abb346 91612c33
......@@ -81,11 +81,14 @@
#define I40E_DEFAULT_MSG_ENABLE 4
#define I40E_NVM_VERSION_LO_SHIFT 0
#define I40E_NVM_VERSION_LO_MASK (0xf << I40E_NVM_VERSION_LO_SHIFT)
#define I40E_NVM_VERSION_MID_SHIFT 4
#define I40E_NVM_VERSION_MID_MASK (0xff << I40E_NVM_VERSION_MID_SHIFT)
#define I40E_NVM_VERSION_HI_SHIFT 12
#define I40E_NVM_VERSION_HI_MASK (0xf << I40E_NVM_VERSION_HI_SHIFT)
#define I40E_NVM_VERSION_LO_MASK (0xff << I40E_NVM_VERSION_LO_SHIFT)
#define I40E_NVM_VERSION_HI_SHIFT 8
#define I40E_NVM_VERSION_HI_MASK (0xff << I40E_NVM_VERSION_HI_SHIFT)
/* The values in here are decimal coded as hex as is the case in the NVM map*/
#define I40E_CURRENT_NVM_VERSION_HI 0x2
#define I40E_CURRENT_NVM_VERSION_LO 0x1
/* magic for getting defines into strings */
#define STRINGIFY(foo) #foo
......@@ -127,6 +130,7 @@ enum i40e_state_t {
__I40E_PF_RESET_REQUESTED,
__I40E_CORE_RESET_REQUESTED,
__I40E_GLOBAL_RESET_REQUESTED,
__I40E_EMP_RESET_REQUESTED,
__I40E_FILTER_OVERFLOW_PROMISC,
};
......@@ -247,6 +251,7 @@ struct i40e_pf {
u16 globr_count; /* Global reset count */
u16 empr_count; /* EMP reset count */
u16 pfr_count; /* PF reset count */
u16 sw_int_count; /* SW interrupt count */
struct mutex switch_mutex;
u16 lan_vsi; /* our default LAN VSI */
......@@ -441,13 +446,11 @@ static inline char *i40e_fw_version_str(struct i40e_hw *hw)
static char buf[32];
snprintf(buf, sizeof(buf),
"f%d.%d a%d.%d n%02d.%02d.%02d e%08x",
"f%d.%d a%d.%d n%02x.%02x e%08x",
hw->aq.fw_maj_ver, hw->aq.fw_min_ver,
hw->aq.api_maj_ver, hw->aq.api_min_ver,
(hw->nvm.version & I40E_NVM_VERSION_HI_MASK)
>> I40E_NVM_VERSION_HI_SHIFT,
(hw->nvm.version & I40E_NVM_VERSION_MID_MASK)
>> I40E_NVM_VERSION_MID_SHIFT,
(hw->nvm.version & I40E_NVM_VERSION_LO_MASK)
>> I40E_NVM_VERSION_LO_SHIFT,
hw->nvm.eetrack);
......
......@@ -43,13 +43,17 @@ static void i40e_adminq_init_regs(struct i40e_hw *hw)
if (hw->mac.type == I40E_MAC_VF) {
hw->aq.asq.tail = I40E_VF_ATQT1;
hw->aq.asq.head = I40E_VF_ATQH1;
hw->aq.asq.len = I40E_VF_ATQLEN1;
hw->aq.arq.tail = I40E_VF_ARQT1;
hw->aq.arq.head = I40E_VF_ARQH1;
hw->aq.arq.len = I40E_VF_ARQLEN1;
} else {
hw->aq.asq.tail = I40E_PF_ATQT;
hw->aq.asq.head = I40E_PF_ATQH;
hw->aq.asq.len = I40E_PF_ATQLEN;
hw->aq.arq.tail = I40E_PF_ARQT;
hw->aq.arq.head = I40E_PF_ARQH;
hw->aq.arq.len = I40E_PF_ARQLEN;
}
}
......@@ -466,10 +470,9 @@ static i40e_status i40e_shutdown_asq(struct i40e_hw *hw)
return I40E_ERR_NOT_READY;
/* Stop firmware AdminQ processing */
if (hw->mac.type == I40E_MAC_VF)
wr32(hw, I40E_VF_ATQLEN1, 0);
else
wr32(hw, I40E_PF_ATQLEN, 0);
wr32(hw, hw->aq.asq.head, 0);
wr32(hw, hw->aq.asq.tail, 0);
wr32(hw, hw->aq.asq.len, 0);
/* make sure lock is available */
mutex_lock(&hw->aq.asq_mutex);
......@@ -500,10 +503,9 @@ static i40e_status i40e_shutdown_arq(struct i40e_hw *hw)
return I40E_ERR_NOT_READY;
/* Stop firmware AdminQ processing */
if (hw->mac.type == I40E_MAC_VF)
wr32(hw, I40E_VF_ARQLEN1, 0);
else
wr32(hw, I40E_PF_ARQLEN, 0);
wr32(hw, hw->aq.arq.head, 0);
wr32(hw, hw->aq.arq.tail, 0);
wr32(hw, hw->aq.arq.len, 0);
/* make sure lock is available */
mutex_lock(&hw->aq.arq_mutex);
......@@ -533,8 +535,9 @@ static i40e_status i40e_shutdown_arq(struct i40e_hw *hw)
**/
i40e_status i40e_init_adminq(struct i40e_hw *hw)
{
u16 eetrack_lo, eetrack_hi;
i40e_status ret_code;
u16 eetrack_lo, eetrack_hi;
int retry = 0;
/* verify input for valid configuration */
if ((hw->aq.num_arq_entries == 0) ||
......@@ -562,11 +565,24 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
if (ret_code)
goto init_adminq_free_asq;
ret_code = i40e_aq_get_firmware_version(hw,
&hw->aq.fw_maj_ver, &hw->aq.fw_min_ver,
&hw->aq.api_maj_ver, &hw->aq.api_min_ver,
NULL);
if (ret_code)
/* There are some cases where the firmware may not be quite ready
* for AdminQ operations, so we retry the AdminQ setup a few times
* if we see timeouts in this first AQ call.
*/
do {
ret_code = i40e_aq_get_firmware_version(hw,
&hw->aq.fw_maj_ver,
&hw->aq.fw_min_ver,
&hw->aq.api_maj_ver,
&hw->aq.api_min_ver,
NULL);
if (ret_code != I40E_ERR_ADMIN_QUEUE_TIMEOUT)
break;
retry++;
msleep(100);
i40e_resume_aq(hw);
} while (retry < 10);
if (ret_code != I40E_SUCCESS)
goto init_adminq_free_arq;
if (hw->aq.api_maj_ver != I40E_FW_API_VERSION_MAJOR ||
......@@ -956,27 +972,13 @@ void i40e_resume_aq(struct i40e_hw *hw)
hw->aq.asq.next_to_clean = 0;
i40e_config_asq_regs(hw);
reg = hw->aq.num_asq_entries;
if (hw->mac.type == I40E_MAC_VF) {
reg |= I40E_VF_ATQLEN_ATQENABLE_MASK;
wr32(hw, I40E_VF_ATQLEN1, reg);
} else {
reg |= I40E_PF_ATQLEN_ATQENABLE_MASK;
wr32(hw, I40E_PF_ATQLEN, reg);
}
reg = hw->aq.num_asq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK;
wr32(hw, hw->aq.asq.len, reg);
hw->aq.arq.next_to_use = 0;
hw->aq.arq.next_to_clean = 0;
i40e_config_arq_regs(hw);
reg = hw->aq.num_arq_entries;
if (hw->mac.type == I40E_MAC_VF) {
reg |= I40E_VF_ATQLEN_ATQENABLE_MASK;
wr32(hw, I40E_VF_ARQLEN1, reg);
} else {
reg |= I40E_PF_ATQLEN_ATQENABLE_MASK;
wr32(hw, I40E_PF_ARQLEN, reg);
}
reg = hw->aq.num_arq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK;
wr32(hw, hw->aq.arq.len, reg);
}
......@@ -56,6 +56,7 @@ struct i40e_adminq_ring {
/* used for queue tracking */
u32 head;
u32 tail;
u32 len;
};
/* ASQ transaction details */
......
......@@ -297,7 +297,11 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
}
/* Determine the PF number based on the PCI fn */
hw->pf_id = (u8)hw->bus.func;
reg = rd32(hw, I40E_GLPCI_CAPSUP);
if (reg & I40E_GLPCI_CAPSUP_ARI_EN_MASK)
hw->pf_id = (u8)((hw->bus.device << 3) | hw->bus.func);
else
hw->pf_id = (u8)hw->bus.func;
/* If there was a Global Reset in progress when we got here,
* we don't need to do the PF Reset
......
......@@ -1472,6 +1472,10 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
dev_info(&pf->pdev->dev, "forcing GlobR\n");
i40e_do_reset(pf, (1 << __I40E_GLOBAL_RESET_REQUESTED));
} else if (strncmp(cmd_buf, "empr", 4) == 0) {
dev_info(&pf->pdev->dev, "forcing EMPR\n");
i40e_do_reset(pf, (1 << __I40E_EMP_RESET_REQUESTED));
} else if (strncmp(cmd_buf, "read", 4) == 0) {
u32 address;
u32 value;
......
......@@ -68,16 +68,16 @@ static i40e_status i40e_diag_reg_pattern_test(struct i40e_hw *hw,
struct i40e_diag_reg_test_info i40e_reg_list[] = {
/* offset mask elements stride */
{I40E_QTX_CTL(0), 0x0000FFBF, 64, I40E_QTX_CTL(1) - I40E_QTX_CTL(0)},
{I40E_QTX_CTL(0), 0x0000FFBF, 4, I40E_QTX_CTL(1) - I40E_QTX_CTL(0)},
{I40E_PFINT_ITR0(0), 0x00000FFF, 3, I40E_PFINT_ITR0(1) - I40E_PFINT_ITR0(0)},
{I40E_PFINT_ITRN(0, 0), 0x00000FFF, 64, I40E_PFINT_ITRN(0, 1) - I40E_PFINT_ITRN(0, 0)},
{I40E_PFINT_ITRN(1, 0), 0x00000FFF, 64, I40E_PFINT_ITRN(1, 1) - I40E_PFINT_ITRN(1, 0)},
{I40E_PFINT_ITRN(2, 0), 0x00000FFF, 64, I40E_PFINT_ITRN(2, 1) - I40E_PFINT_ITRN(2, 0)},
{I40E_PFINT_STAT_CTL0, 0x0000000C, 1, 0},
{I40E_PFINT_LNKLST0, 0x00001FFF, 1, 0},
{I40E_PFINT_LNKLSTN(0), 0x000007FF, 511, I40E_PFINT_LNKLSTN(1) - I40E_PFINT_LNKLSTN(0)},
{I40E_QINT_TQCTL(0), 0x000000FF, I40E_QINT_TQCTL_MAX_INDEX + 1, I40E_QINT_TQCTL(1) - I40E_QINT_TQCTL(0)},
{I40E_QINT_RQCTL(0), 0x000000FF, I40E_QINT_RQCTL_MAX_INDEX + 1, I40E_QINT_RQCTL(1) - I40E_QINT_RQCTL(0)},
{I40E_PFINT_LNKLSTN(0), 0x000007FF, 64, I40E_PFINT_LNKLSTN(1) - I40E_PFINT_LNKLSTN(0)},
{I40E_QINT_TQCTL(0), 0x000000FF, 64, I40E_QINT_TQCTL(1) - I40E_QINT_TQCTL(0)},
{I40E_QINT_RQCTL(0), 0x000000FF, 64, I40E_QINT_RQCTL(1) - I40E_QINT_RQCTL(0)},
{I40E_PFINT_ICR0_ENA, 0xF7F20000, 1, 0},
{ 0 }
};
......
......@@ -734,14 +734,20 @@ static int i40e_eeprom_test(struct i40e_pf *pf, u64 *data)
static int i40e_intr_test(struct i40e_pf *pf, u64 *data)
{
*data = -ENOSYS;
u16 swc_old = pf->sw_int_count;
wr32(&pf->hw, I40E_PFINT_DYN_CTL0,
(I40E_PFINT_DYN_CTL0_INTENA_MASK |
I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK));
usleep_range(1000, 2000);
*data = (swc_old == pf->sw_int_count);
return *data;
}
static int i40e_loopback_test(struct i40e_pf *pf, u64 *data)
{
*data = -ENOSYS;
*data = 0;
return *data;
}
......
......@@ -113,8 +113,8 @@ enum i40e_hmc_lan_object_size {
#define I40E_HMC_L2OBJ_BASE_ALIGNMENT 512
#define I40E_HMC_OBJ_SIZE_TXQ 128
#define I40E_HMC_OBJ_SIZE_RXQ 32
#define I40E_HMC_OBJ_SIZE_FCOE_CNTX 128
#define I40E_HMC_OBJ_SIZE_FCOE_FILT 32
#define I40E_HMC_OBJ_SIZE_FCOE_CNTX 64
#define I40E_HMC_OBJ_SIZE_FCOE_FILT 64
enum i40e_hmc_lan_rsrc_type {
I40E_HMC_LAN_FULL = 0,
......
......@@ -2752,6 +2752,11 @@ static irqreturn_t i40e_intr(int irq, void *data)
ena_mask = rd32(hw, I40E_PFINT_ICR0_ENA);
/* if interrupt but no bits showing, must be SWINT */
if (((icr0 & ~I40E_PFINT_ICR0_INTEVENT_MASK) == 0) ||
(icr0 & I40E_PFINT_ICR0_SWINT_MASK))
pf->sw_int_count++;
/* only q0 is used in MSI/Legacy mode, and none are used in MSIX */
if (icr0 & I40E_PFINT_ICR0_QUEUE_0_MASK) {
......@@ -2790,11 +2795,11 @@ static irqreturn_t i40e_intr(int irq, void *data)
val = rd32(hw, I40E_GLGEN_RSTAT);
val = (val & I40E_GLGEN_RSTAT_RESET_TYPE_MASK)
>> I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT;
if (val & I40E_RESET_CORER)
if (val == I40E_RESET_CORER)
pf->corer_count++;
else if (val & I40E_RESET_GLOBR)
else if (val == I40E_RESET_GLOBR)
pf->globr_count++;
else if (val & I40E_RESET_EMPR)
else if (val == I40E_RESET_EMPR)
pf->empr_count++;
}
......@@ -4051,6 +4056,24 @@ void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags)
wr32(&pf->hw, I40E_GLGEN_RTRIG, val);
i40e_flush(&pf->hw);
} else if (reset_flags & (1 << __I40E_EMP_RESET_REQUESTED)) {
/* Request a Firmware Reset
*
* Same as Global reset, plus restarting the
* embedded firmware engine.
*/
/* enable EMP Reset */
val = rd32(&pf->hw, I40E_GLGEN_RSTENA_EMP);
val |= I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_MASK;
wr32(&pf->hw, I40E_GLGEN_RSTENA_EMP, val);
/* force the reset */
val = rd32(&pf->hw, I40E_GLGEN_RTRIG);
val |= I40E_GLGEN_RTRIG_EMPFWR_MASK;
wr32(&pf->hw, I40E_GLGEN_RTRIG, val);
i40e_flush(&pf->hw);
} else if (reset_flags & (1 << __I40E_PF_RESET_REQUESTED)) {
/* Request a PF Reset
......@@ -5579,6 +5602,7 @@ static int i40e_sw_init(struct i40e_pf *pf)
pf->msg_enable = netif_msg_init(I40E_DEFAULT_MSG_ENABLE,
(NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK));
pf->hw.debug_mask = pf->msg_enable | I40E_DEBUG_DIAG;
if (debug != -1 && debug != I40E_DEFAULT_MSG_ENABLE) {
if (I40E_DEBUG_USER & debug)
pf->hw.debug_mask = debug;
......@@ -7141,6 +7165,13 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = i40e_init_adminq(hw);
dev_info(&pdev->dev, "%s\n", i40e_fw_version_str(hw));
if (((hw->nvm.version & I40E_NVM_VERSION_HI_MASK)
>> I40E_NVM_VERSION_HI_SHIFT) != I40E_CURRENT_NVM_VERSION_HI) {
dev_info(&pdev->dev,
"warning: NVM version not supported, supported version: %02x.%02x\n",
I40E_CURRENT_NVM_VERSION_HI,
I40E_CURRENT_NVM_VERSION_LO);
}
if (err) {
dev_info(&pdev->dev,
"init_adminq failed: %d expecting API %02x.%02x\n",
......
......@@ -852,10 +852,7 @@ struct i40e_filter_program_desc {
/* Packet Classifier Types for filters */
enum i40e_filter_pctype {
/* Note: Value 0-25 are reserved for future use */
I40E_FILTER_PCTYPE_IPV4_TEREDO_UDP = 26,
I40E_FILTER_PCTYPE_IPV6_TEREDO_UDP = 27,
I40E_FILTER_PCTYPE_NONF_IPV4_1588_UDP = 28,
/* Note: Values 0-28 are reserved for future use */
I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP = 29,
I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP = 30,
I40E_FILTER_PCTYPE_NONF_IPV4_UDP = 31,
......@@ -864,8 +861,7 @@ enum i40e_filter_pctype {
I40E_FILTER_PCTYPE_NONF_IPV4_SCTP = 34,
I40E_FILTER_PCTYPE_NONF_IPV4_OTHER = 35,
I40E_FILTER_PCTYPE_FRAG_IPV4 = 36,
/* Note: Value 37 is reserved for future use */
I40E_FILTER_PCTYPE_NONF_IPV6_1588_UDP = 38,
/* Note: Values 37-38 are reserved for future use */
I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP = 39,
I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP = 40,
I40E_FILTER_PCTYPE_NONF_IPV6_UDP = 41,
......@@ -877,7 +873,8 @@ enum i40e_filter_pctype {
/* Note: Value 47 is reserved for future use */
I40E_FILTER_PCTYPE_FCOE_OX = 48,
I40E_FILTER_PCTYPE_FCOE_RX = 49,
/* Note: Value 50-62 are reserved for future use */
I40E_FILTER_PCTYPE_FCOE_OTHER = 50,
/* Note: Values 51-62 are reserved for future use */
I40E_FILTER_PCTYPE_L2_PAYLOAD = 63,
};
......
......@@ -70,7 +70,7 @@ static inline bool i40e_vc_isvalid_vector_id(struct i40e_vf *vf, u8 vector_id)
{
struct i40e_pf *pf = vf->pf;
return vector_id < pf->hw.func_caps.num_msix_vectors_vf;
return vector_id <= pf->hw.func_caps.num_msix_vectors_vf;
}
/***********************vf resource mgmt routines*****************/
......@@ -620,13 +620,13 @@ int i40e_reset_vf(struct i40e_vf *vf, bool flr)
if (ret)
dev_info(&pf->pdev->dev,
"Queue control check failed on Tx queue %d of VSI %d VF %d\n",
vf->lan_vsi_index, j, vf->vf_id);
j, vf->lan_vsi_index, vf->vf_id);
ret = i40e_ctrl_vsi_rx_queue(vf, vf->lan_vsi_index, j,
I40E_QUEUE_CTRL_FASTDISABLECHECK);
if (ret)
dev_info(&pf->pdev->dev,
"Queue control check failed on Rx queue %d of VSI %d VF %d\n",
vf->lan_vsi_index, j, vf->vf_id);
j, vf->lan_vsi_index, vf->vf_id);
}
/* clear the irq settings */
......@@ -1603,7 +1603,7 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
struct i40e_mac_filter *f;
f = i40e_find_mac(vsi, al->list[i].addr, true, false);
if (f) {
if (!f) {
if (i40e_is_vsi_in_vlan(vsi))
f = i40e_put_mac_in_vlan(vsi, al->list[i].addr,
true, false);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment