diff options
author | David S. Miller <davem@davemloft.net> | 2014-06-11 12:25:12 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-11 12:25:12 -0700 |
commit | d4f3862017f9aaa1a6b6bade396a99a4b77e2cb2 (patch) | |
tree | 7da4b587f102f9c74f6b04205232e037fa39fec9 | |
parent | 813ebbbf8e6c3d03b2a340ed10b88b551a531452 (diff) | |
parent | f832090249d97c4070230fe225e12dc6126a92d1 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next
Jeff Kirsher says:
====================
Intel Wired LAN Driver Updates 2014-06-11
This series contains updates to igb, i40e and i40evf.
Todd makes a change to igb to un-hide invariant returns by getting rid of
the E1000_SUCCESS define and converting those returns to return 0.
Jacob separates the hardware logic from the set function, so that we can
re-use it during a ptp_reset in igb. This enables the reset to return
functionality to the last know timestamp mode, rather than resetting the
value.
Ashish implements context flags for headwb and headwb_addr so that we
do not have to keep them always enabled.
Shannon updates the admin queue API for the new firmware, which adds
set_pf_content, nvm_config_read/write, replaces set_phy_reset with
set_phy_debug and removes nvm_read/write_reg_se. Cleans up the driver
to use the stored base_queue value since there is no need to read the
PCI register for the PF's base queue on every single transmit queue
enable and disable as we already have the value stored from reading
the capability features at startup.
Anjali changes the notion of source and destination for FD_SB in ethtool
to align i40e with other drivers. Adds flow director statistics to
the PF stats. Fixes a bug in ethtool for flow director drop packet
filter where the drop action comes down as a ring_cookie value, so allow
it as a special value that can be used to configure destination control.
Mitch fixes the i40evf to keep the driver from going down when it is
already in a down state. This prevents a CPU soft lock in napi_disable().
Also change the i40evf to check the admin queue error bits since the
firmware can indicate any admin queue error states to the driver via
some bits in the length registers.
Neerav separates out the DCB capability and enabled flags because currently
if the firmware reports DCB capability the driver enables
I40E_FLAG_DCB_ENABLED flag. When this flag is enabled the driver inserts
a tag when transmitting a packet from the port even if there are no DCB
traffic classes configured at the port. So by adding the additional flag,
I40E_FLAG_DCB_CAPABLE, that will be set when the DCB capability is present
and the existing enabled flag will only be set if there are more than one
traffic classes configured at the port.
Greg fixes the i40e driver to not automatically accept tagged packets by
default so that the system must request a VLAN tag packet filter to get
packets with that tag. Greg also converts i40e to use the in-kernel
ether_addr_copy() instead of mempcy().
Jesse removes the FTYPE field from the receive descriptor to match the
hardware implementation.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
20 files changed, 453 insertions, 174 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 2af28fd37bff..65985846345d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -154,11 +154,23 @@ struct i40e_lump_tracking { #define I40E_FDIR_BUFFER_FULL_MARGIN 10 #define I40E_FDIR_BUFFER_HEAD_ROOM 200 +enum i40e_fd_stat_idx { + I40E_FD_STAT_ATR, + I40E_FD_STAT_SB, + I40E_FD_STAT_PF_COUNT +}; +#define I40E_FD_STAT_PF_IDX(pf_id) ((pf_id) * I40E_FD_STAT_PF_COUNT) +#define I40E_FD_ATR_STAT_IDX(pf_id) \ + (I40E_FD_STAT_PF_IDX(pf_id) + I40E_FD_STAT_ATR) +#define I40E_FD_SB_STAT_IDX(pf_id) \ + (I40E_FD_STAT_PF_IDX(pf_id) + I40E_FD_STAT_SB) + struct i40e_fdir_filter { struct hlist_node fdir_node; /* filter ipnut set */ u8 flow_type; u8 ip4_proto; + /* TX packet view of src and dst */ __be32 dst_ip[4]; __be32 src_ip[4]; __be16 src_port; @@ -222,6 +234,8 @@ struct i40e_pf { struct hlist_head fdir_filter_list; u16 fdir_pf_active_filters; + u16 fd_sb_cnt_idx; + u16 fd_atr_cnt_idx; #ifdef CONFIG_I40E_VXLAN __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; @@ -263,6 +277,7 @@ struct i40e_pf { #ifdef CONFIG_I40E_VXLAN #define I40E_FLAG_VXLAN_FILTER_SYNC (u64)(1 << 27) #endif +#define I40E_FLAG_DCB_CAPABLE (u64)(1 << 29) /* tracks features that get auto disabled by errors */ u64 auto_disable_flags; diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h index f2ba4b76ecd3..15f289f2917f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h @@ -34,7 +34,7 @@ */ #define I40E_FW_API_VERSION_MAJOR 0x0001 -#define I40E_FW_API_VERSION_MINOR 0x0001 +#define I40E_FW_API_VERSION_MINOR 0x0002 struct i40e_aq_desc { __le16 flags; @@ -123,6 +123,7 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_get_version = 0x0001, i40e_aqc_opc_driver_version = 0x0002, i40e_aqc_opc_queue_shutdown = 0x0003, + i40e_aqc_opc_set_pf_context = 0x0004, /* resource ownership */ i40e_aqc_opc_request_resource = 0x0008, @@ -222,13 +223,15 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_get_partner_advt = 0x0616, i40e_aqc_opc_set_lb_modes = 0x0618, i40e_aqc_opc_get_phy_wol_caps = 0x0621, - i40e_aqc_opc_set_phy_reset = 0x0622, + i40e_aqc_opc_set_phy_debug = 0x0622, i40e_aqc_opc_upload_ext_phy_fm = 0x0625, /* NVM commands */ - i40e_aqc_opc_nvm_read = 0x0701, - i40e_aqc_opc_nvm_erase = 0x0702, - i40e_aqc_opc_nvm_update = 0x0703, + i40e_aqc_opc_nvm_read = 0x0701, + i40e_aqc_opc_nvm_erase = 0x0702, + i40e_aqc_opc_nvm_update = 0x0703, + i40e_aqc_opc_nvm_config_read = 0x0704, + i40e_aqc_opc_nvm_config_write = 0x0705, /* virtualization commands */ i40e_aqc_opc_send_msg_to_pf = 0x0801, @@ -270,8 +273,6 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_debug_set_mode = 0xFF01, i40e_aqc_opc_debug_read_reg = 0xFF03, i40e_aqc_opc_debug_write_reg = 0xFF04, - i40e_aqc_opc_debug_read_reg_sg = 0xFF05, - i40e_aqc_opc_debug_write_reg_sg = 0xFF06, i40e_aqc_opc_debug_modify_reg = 0xFF07, i40e_aqc_opc_debug_dump_internals = 0xFF08, i40e_aqc_opc_debug_modify_internals = 0xFF09, @@ -339,6 +340,14 @@ struct i40e_aqc_queue_shutdown { I40E_CHECK_CMD_LENGTH(i40e_aqc_queue_shutdown); +/* Set PF context (0x0004, direct) */ +struct i40e_aqc_set_pf_context { + u8 pf_id; + u8 reserved[15]; +}; + +I40E_CHECK_CMD_LENGTH(i40e_aqc_set_pf_context); + /* Request resource ownership (direct 0x0008) * Release resource ownership (direct 0x0009) */ @@ -1404,11 +1413,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_switching_comp_bw_limit); struct i40e_aqc_configure_switching_comp_ets_data { u8 reserved[4]; u8 tc_valid_bits; - u8 reserved1; + u8 seepage; +#define I40E_AQ_ETS_SEEPAGE_EN_MASK 0x1 u8 tc_strict_priority_flags; - u8 reserved2[17]; + u8 reserved1[17]; u8 tc_bw_share_credits[8]; - u8 reserved3[96]; + u8 reserved2[96]; }; /* Configure Switching Component Bandwidth Limits per Tc (indirect 0x0416) */ @@ -1525,6 +1535,8 @@ enum i40e_aq_phy_type { I40E_PHY_TYPE_XLPPI = 0x9, I40E_PHY_TYPE_40GBASE_CR4_CU = 0xA, I40E_PHY_TYPE_10GBASE_CR1_CU = 0xB, + I40E_PHY_TYPE_10GBASE_AOC = 0xC, + I40E_PHY_TYPE_40GBASE_AOC = 0xD, I40E_PHY_TYPE_100BASE_TX = 0x11, I40E_PHY_TYPE_1000BASE_T = 0x12, I40E_PHY_TYPE_10GBASE_T = 0x13, @@ -1535,7 +1547,10 @@ enum i40e_aq_phy_type { I40E_PHY_TYPE_40GBASE_CR4 = 0x18, I40E_PHY_TYPE_40GBASE_SR4 = 0x19, I40E_PHY_TYPE_40GBASE_LR4 = 0x1A, - I40E_PHY_TYPE_20GBASE_KR2 = 0x1B, + I40E_PHY_TYPE_1000BASE_SX = 0x1B, + I40E_PHY_TYPE_1000BASE_LX = 0x1C, + I40E_PHY_TYPE_1000BASE_T_OPTICAL = 0x1D, + I40E_PHY_TYPE_20GBASE_KR2 = 0x1E, I40E_PHY_TYPE_MAX }; @@ -1679,6 +1694,7 @@ struct i40e_aqc_get_link_status { #define I40E_AQ_LINK_TX_ACTIVE 0x00 #define I40E_AQ_LINK_TX_DRAINED 0x01 #define I40E_AQ_LINK_TX_FLUSHED 0x03 +#define I40E_AQ_LINK_FORCED_40G 0x10 u8 loopback; /* use defines from i40e_aqc_set_lb_mode */ __le16 max_frame_size; u8 config; @@ -1730,14 +1746,21 @@ struct i40e_aqc_set_lb_mode { I40E_CHECK_CMD_LENGTH(i40e_aqc_set_lb_mode); -/* Set PHY Reset command (0x0622) */ -struct i40e_aqc_set_phy_reset { - u8 reset_flags; -#define I40E_AQ_PHY_RESET_REQUEST 0x02 +/* Set PHY Debug command (0x0622) */ +struct i40e_aqc_set_phy_debug { + u8 command_flags; +#define I40E_AQ_PHY_DEBUG_RESET_INTERNAL 0x02 +#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SHIFT 2 +#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_MASK (0x03 << \ + I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SHIFT) +#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_NONE 0x00 +#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_HARD 0x01 +#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SOFT 0x02 +#define I40E_AQ_PHY_DEBUG_DISABLE_LINK_FW 0x10 u8 reserved[15]; }; -I40E_CHECK_CMD_LENGTH(i40e_aqc_set_phy_reset); +I40E_CHECK_CMD_LENGTH(i40e_aqc_set_phy_debug); enum i40e_aq_phy_reg_type { I40E_AQC_PHY_REG_INTERNAL = 0x1, @@ -1762,6 +1785,47 @@ struct i40e_aqc_nvm_update { I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_update); +/* NVM Config Read (indirect 0x0704) */ +struct i40e_aqc_nvm_config_read { + __le16 cmd_flags; +#define ANVM_SINGLE_OR_MULTIPLE_FEATURES_MASK 1 +#define ANVM_READ_SINGLE_FEATURE 0 +#define ANVM_READ_MULTIPLE_FEATURES 1 + __le16 element_count; + __le16 element_id; /* Feature/field ID */ + u8 reserved[2]; + __le32 address_high; + __le32 address_low; +}; + +I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_config_read); + +/* NVM Config Write (indirect 0x0705) */ +struct i40e_aqc_nvm_config_write { + __le16 cmd_flags; + __le16 element_count; + u8 reserved[4]; + __le32 address_high; + __le32 address_low; +}; + +I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_config_write); + +struct i40e_aqc_nvm_config_data_feature { + __le16 feature_id; + __le16 instance_id; + __le16 feature_options; + __le16 feature_selection; +}; + +struct i40e_aqc_nvm_config_data_immediate_field { +#define ANVM_FEATURE_OR_IMMEDIATE_MASK 0x2 + __le16 field_id; + __le16 instance_id; + __le16 field_options; + __le16 field_value; +}; + /* Send to PF command (indirect 0x0801) id is only used by PF * Send to VF command (indirect 0x0802) id is only used by PF * Send to Peer PF command (indirect 0x0803) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 8e4b33c3e3cd..6e65f19dd6e5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -665,10 +665,9 @@ i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr) **/ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable) { - u32 reg_val = rd32(hw, I40E_PFLAN_QALLOC); - u32 first_queue = (reg_val & I40E_PFLAN_QALLOC_FIRSTQ_MASK); - u32 abs_queue_idx = first_queue + queue; + u32 abs_queue_idx = hw->func_caps.base_queue + queue; u32 reg_block = 0; + u32 reg_val; if (abs_queue_idx >= 128) reg_block = abs_queue_idx / 128; diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c index 871831a535d0..00bc0cdb3a03 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c +++ b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c @@ -302,8 +302,8 @@ void i40e_dcbnl_setup(struct i40e_vsi *vsi) struct net_device *dev = vsi->netdev; struct i40e_pf *pf = i40e_netdev_to_pf(dev); - /* DCB not enabled */ - if (!(pf->flags & I40E_FLAG_DCB_ENABLED)) + /* Not DCB capable */ + if (!(pf->flags & I40E_FLAG_DCB_CAPABLE)) return; /* Do not setup DCB NL ops for MFP mode */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index b16c25111552..4a488ffcd6b0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -145,6 +145,9 @@ static struct i40e_stats i40e_gstrings_stats[] = { I40E_PF_STAT("rx_jabber", stats.rx_jabber), I40E_PF_STAT("VF_admin_queue_requests", vf_aq_requests), I40E_PF_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), + I40E_PF_STAT("fdir_atr_match", stats.fd_atr_match), + I40E_PF_STAT("fdir_sb_match", stats.fd_sb_match), + /* LPI stats */ I40E_PF_STAT("tx_lpi_status", stats.tx_lpi_status), I40E_PF_STAT("rx_lpi_status", stats.rx_lpi_status), @@ -1249,11 +1252,18 @@ static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf, fsp->m_u.usr_ip4_spec.proto = 0; } - fsp->h_u.tcp_ip4_spec.psrc = rule->src_port; - fsp->h_u.tcp_ip4_spec.pdst = rule->dst_port; - fsp->h_u.tcp_ip4_spec.ip4src = rule->src_ip[0]; - fsp->h_u.tcp_ip4_spec.ip4dst = rule->dst_ip[0]; - fsp->ring_cookie = rule->q_index; + /* Reverse the src and dest notion, since the HW views them from + * Tx perspective where as the user expects it from Rx filter view. + */ + fsp->h_u.tcp_ip4_spec.psrc = rule->dst_port; + fsp->h_u.tcp_ip4_spec.pdst = rule->src_port; + fsp->h_u.tcp_ip4_spec.ip4src = rule->dst_ip[0]; + fsp->h_u.tcp_ip4_spec.ip4dst = rule->src_ip[0]; + + if (rule->dest_ctl == I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET) + fsp->ring_cookie = RX_CLS_FLOW_DISC; + else + fsp->ring_cookie = rule->q_index; return 0; } @@ -1557,7 +1567,8 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi, return -EINVAL; } - if (fsp->ring_cookie >= vsi->num_queue_pairs) + if ((fsp->ring_cookie != RX_CLS_FLOW_DISC) && + (fsp->ring_cookie >= vsi->num_queue_pairs)) return -EINVAL; input = kzalloc(sizeof(*input), GFP_KERNEL); @@ -1578,13 +1589,17 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi, input->pctype = 0; input->dest_vsi = vsi->id; input->fd_status = I40E_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID; - input->cnt_index = 0; + input->cnt_index = pf->fd_sb_cnt_idx; input->flow_type = fsp->flow_type; input->ip4_proto = fsp->h_u.usr_ip4_spec.proto; - input->src_port = fsp->h_u.tcp_ip4_spec.psrc; - input->dst_port = fsp->h_u.tcp_ip4_spec.pdst; - input->src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src; - input->dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst; + + /* Reverse the src and dest notion, since the HW expects them to be from + * Tx perspective where as the input from user is from Rx filter view. + */ + input->dst_port = fsp->h_u.tcp_ip4_spec.psrc; + input->src_port = fsp->h_u.tcp_ip4_spec.pdst; + input->dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src; + input->src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst; ret = i40e_add_del_fdir(vsi, input, true); if (ret) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 145cb9fc1516..a84ddaf06a68 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -39,7 +39,7 @@ static const char i40e_driver_string[] = #define DRV_VERSION_MAJOR 0 #define DRV_VERSION_MINOR 4 -#define DRV_VERSION_BUILD 7 +#define DRV_VERSION_BUILD 10 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_BUILD) DRV_KERN @@ -1013,6 +1013,14 @@ static void i40e_update_pf_stats(struct i40e_pf *pf) pf->stat_offsets_loaded, &osd->rx_jabber, &nsd->rx_jabber); + /* FDIR stats */ + i40e_stat_update32(hw, I40E_GLQF_PCNT(pf->fd_atr_cnt_idx), + pf->stat_offsets_loaded, + &osd->fd_atr_match, &nsd->fd_atr_match); + i40e_stat_update32(hw, I40E_GLQF_PCNT(pf->fd_sb_cnt_idx), + pf->stat_offsets_loaded, + &osd->fd_sb_match, &nsd->fd_sb_match); + val = rd32(hw, I40E_PRTPM_EEE_STAT); nsd->tx_lpi_status = (val & I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK) >> @@ -1154,6 +1162,30 @@ struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr, } /** + * i40e_rm_default_mac_filter - Remove the default MAC filter set by NVM + * @vsi: the PF Main VSI - inappropriate for any other VSI + * @macaddr: the MAC address + **/ +static void i40e_rm_default_mac_filter(struct i40e_vsi *vsi, u8 *macaddr) +{ + struct i40e_aqc_remove_macvlan_element_data element; + struct i40e_pf *pf = vsi->back; + i40e_status aq_ret; + + /* Only appropriate for the PF main VSI */ + if (vsi->type != I40E_VSI_MAIN) + return; + + ether_addr_copy(element.mac_addr, macaddr); + element.vlan_tag = 0; + element.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH | + I40E_AQC_MACVLAN_DEL_IGNORE_VLAN; + aq_ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid, &element, 1, NULL); + if (aq_ret) + dev_err(&pf->pdev->dev, "Could not remove default MAC-VLAN\n"); +} + +/** * i40e_add_filter - Add a mac/vlan filter to the VSI * @vsi: the VSI to be searched * @macaddr: the MAC address @@ -1178,7 +1210,7 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi, if (!f) goto add_filter_out; - memcpy(f->macaddr, macaddr, ETH_ALEN); + ether_addr_copy(f->macaddr, macaddr); f->vlan = vlan; f->changed = true; @@ -1302,7 +1334,7 @@ static int i40e_set_mac(struct net_device *netdev, void *p) return -EADDRNOTAVAIL; } - memcpy(vsi->back->hw.mac.addr, addr->sa_data, netdev->addr_len); + ether_addr_copy(vsi->back->hw.mac.addr, addr->sa_data); } /* In order to be sure to not drop any packets, add the new address @@ -1316,7 +1348,7 @@ static int i40e_set_mac(struct net_device *netdev, void *p) i40e_del_filter(vsi, netdev->dev_addr, I40E_VLAN_ANY, false, false); i40e_sync_vsi_filters(vsi); - memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); + ether_addr_copy(netdev->dev_addr, addr->sa_data); return 0; } @@ -1573,8 +1605,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) cmd_flags = 0; /* add to delete list */ - memcpy(del_list[num_del].mac_addr, - f->macaddr, ETH_ALEN); + ether_addr_copy(del_list[num_del].mac_addr, f->macaddr); del_list[num_del].vlan_tag = cpu_to_le16((u16)(f->vlan == I40E_VLAN_ANY ? 0 : f->vlan)); @@ -1639,8 +1670,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) cmd_flags = 0; /* add to add array */ - memcpy(add_list[num_add].mac_addr, - f->macaddr, ETH_ALEN); + ether_addr_copy(add_list[num_add].mac_addr, f->macaddr); add_list[num_add].vlan_tag = cpu_to_le16( (u16)(f->vlan == I40E_VLAN_ANY ? 0 : f->vlan)); @@ -4130,7 +4160,11 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf) /* When status is not DISABLED then DCBX in FW */ pf->dcbx_cap = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_IEEE; - pf->flags |= I40E_FLAG_DCB_ENABLED; + + pf->flags |= I40E_FLAG_DCB_CAPABLE; + /* Enable DCB tagging only when more than one TC */ + if (i40e_dcb_get_num_tc(&hw->local_dcbx_config) > 1) + pf->flags |= I40E_FLAG_DCB_ENABLED; } } else { dev_info(&pf->pdev->dev, "AQ Querying DCB configuration failed: %d\n", @@ -4685,6 +4719,10 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, int ret = 0; u8 type; + /* Not DCB capable or capability disabled */ + if (!(pf->flags & I40E_FLAG_DCB_CAPABLE)) + return ret; + /* Ignore if event is not for Nearest Bridge */ type = ((mib->type >> I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) & I40E_AQ_LLDP_BRIDGE_TYPE_MASK); @@ -4726,6 +4764,12 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, if (!need_reconfig) goto exit; + /* Enable DCB tagging only when more than one TC */ + if (i40e_dcb_get_num_tc(dcbx_cfg) > 1) + pf->flags |= I40E_FLAG_DCB_ENABLED; + else + pf->flags &= ~I40E_FLAG_DCB_ENABLED; + /* Reconfiguration needed quiesce all VSIs */ i40e_pf_quiesce_all_vsi(pf); @@ -6365,7 +6409,7 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf) if (err) { pf->flags &= ~(I40E_FLAG_MSIX_ENABLED | I40E_FLAG_RSS_ENABLED | - I40E_FLAG_DCB_ENABLED | + I40E_FLAG_DCB_CAPABLE | I40E_FLAG_SRIOV_ENABLED | I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED | @@ -6568,8 +6612,12 @@ static int i40e_sw_init(struct i40e_pf *pf) (pf->hw.func_caps.fd_filters_best_effort > 0)) { pf->flags |= I40E_FLAG_FD_ATR_ENABLED; pf->atr_sample_rate = I40E_DEFAULT_ATR_SAMPLE_RATE; + /* Setup a counter for fd_atr per pf */ + pf->fd_atr_cnt_idx = I40E_FD_ATR_STAT_IDX(pf->hw.pf_id); if (!(pf->flags & I40E_FLAG_MFP_ENABLED)) { pf->flags |= I40E_FLAG_FD_SB_ENABLED; + /* Setup a counter for fd_sb per pf */ + pf->fd_sb_cnt_idx = I40E_FD_SB_STAT_IDX(pf->hw.pf_id); } else { dev_info(&pf->pdev->dev, "Flow Director Sideband mode Disabled in MFP mode\n"); @@ -6965,7 +7013,15 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) if (vsi->type == I40E_VSI_MAIN) { SET_NETDEV_DEV(netdev, &pf->pdev->dev); - memcpy(mac_addr, hw->mac.perm_addr, ETH_ALEN); + ether_addr_copy(mac_addr, hw->mac.perm_addr); + /* The following two steps are necessary to prevent reception + * of tagged packets - by default the NVM loads a MAC-VLAN + * filter that will accept any tagged packet. This is to + * prevent that during normal operations until a specific + * VLAN tag filter has been set. + */ + i40e_rm_default_mac_filter(vsi, mac_addr); + i40e_add_filter(vsi, mac_addr, I40E_VLAN_ANY, false, true); } else { /* relate the VSI_VMDQ name to the VSI_MAIN name */ snprintf(netdev->name, IFNAMSIZ, "%sv%%d", @@ -6975,8 +7031,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) } i40e_add_filter(vsi, brdcast, I40E_VLAN_ANY, false, false); - memcpy(netdev->dev_addr, mac_addr, ETH_ALEN); - memcpy(netdev->perm_addr, mac_addr, ETH_ALEN); + ether_addr_copy(netdev->dev_addr, mac_addr); + ether_addr_copy(netdev->perm_addr, mac_addr); /* vlan gets same features (except vlan offload) * after any tweaks for specific VSI types */ @@ -8187,13 +8243,13 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf) pf->flags &= ~(I40E_FLAG_RSS_ENABLED | I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED | - I40E_FLAG_DCB_ENABLED | + I40E_FLAG_DCB_CAPABLE | I40E_FLAG_SRIOV_ENABLED | I40E_FLAG_VMDQ_ENABLED); } else if (!(pf->flags & (I40E_FLAG_RSS_ENABLED | I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED | - I40E_FLAG_DCB_ENABLED))) { + I40E_FLAG_DCB_CAPABLE))) { /* one qp for PF */ pf->rss_size = pf->num_lan_qps = 1; queues_left -= pf->num_lan_qps; @@ -8205,9 +8261,9 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf) I40E_FLAG_VMDQ_ENABLED); } else { /* Not enough queues for all TCs */ - if ((pf->flags & I40E_FLAG_DCB_ENABLED) && + if ((pf->flags & I40E_FLAG_DCB_CAPABLE) && (queues_left < I40E_MAX_TRAFFIC_CLASS)) { - pf->flags &= ~I40E_FLAG_DCB_ENABLED; + pf->flags &= ~I40E_FLAG_DCB_CAPABLE; dev_info(&pf->pdev->dev, "not enough queues for DCB. DCB is disabled.\n"); } pf->num_lan_qps = pf->rss_size_max; @@ -8300,7 +8356,7 @@ static void i40e_print_features(struct i40e_pf *pf) buf += sprintf(buf, "FD_SB "); buf += sprintf(buf, "NTUPLE "); } - if (pf->flags & I40E_FLAG_DCB_ENABLED) + if (pf->flags & I40E_FLAG_DCB_CAPABLE) buf += sprintf(buf, "DCB "); if (pf->flags & I40E_FLAG_PTP) buf += sprintf(buf, "PTP "); @@ -8478,7 +8534,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_mac_addr; } dev_info(&pdev->dev, "MAC address: %pM\n", hw->mac.addr); - memcpy(hw->mac.perm_addr, hw->mac.addr, ETH_ALEN); + ether_addr_copy(hw->mac.perm_addr, hw->mac.addr); pci_set_drvdata(pdev, pf); pci_save_state(pdev); @@ -8486,7 +8542,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = i40e_init_pf_dcb(pf); if (err) { dev_info(&pdev->dev, "init_pf_dcb failed: %d\n", err); - pf->flags &= ~I40E_FLAG_DCB_ENABLED; + pf->flags &= ~I40E_FLAG_DCB_CAPABLE; /* Continue without DCB enabled */ } #endif /* CONFIG_I40E_DCB */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h index 58c4e1eba5bf..a430699c41d5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h +++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h @@ -70,7 +70,7 @@ i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw, u16 *fw_major_version, u16 *fw_minor_version, u16 *api_major_version, u16 *api_minor_version, struct i40e_asq_cmd_details *cmd_details); -i40e_status i40e_aq_set_phy_reset(struct i40e_hw *hw, +i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags, struct i40e_asq_cmd_details *cmd_details); i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw, u16 vsi_id, struct i40e_asq_cmd_details *cmd_details); diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index d84f4275f470..e49f31dbd5d8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -121,7 +121,7 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet, dcc |= I40E_TXD_FLTR_QW1_CNT_ENA_MASK; dcc |= ((u32)fdir_data->cnt_index << I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) & - I40E_TXD_FLTR_QW1_CNTINDEX_MASK; + I40E_TXD_FLTR_QW1_CNTINDEX_MASK; } fdir_desc->dtype_cmd_cntindex = cpu_to_le32(dcc); @@ -1695,6 +1695,11 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb, dtype_cmd |= I40E_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID << I40E_TXD_FLTR_QW1_FD_STATUS_SHIFT; + dtype_cmd |= I40E_TXD_FLTR_QW1_CNT_ENA_MASK; + dtype_cmd |= + ((u32)pf->fd_atr_cnt_idx << I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) & + I40E_TXD_FLTR_QW1_CNTINDEX_MASK; + fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(flex_ptype); fdir_desc->dtype_cmd_cntindex = cpu_to_le32(dtype_cmd); } diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index 42bfb2aed765..9d39ff23c5fb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -663,7 +663,6 @@ enum i40e_rx_desc_ext_status_bits { I40E_RX_DESC_EXT_STATUS_L2TAG3P_SHIFT = 1, I40E_RX_DESC_EXT_STATUS_FLEXBL_SHIFT = 2, /* 2 BITS */ I40E_RX_DESC_EXT_STATUS_FLEXBH_SHIFT = 4, /* 2 BITS */ - I40E_RX_DESC_EXT_STATUS_FTYPE_SHIFT = 6, /* 3 BITS */ I40E_RX_DESC_EXT_STATUS_FDLONGB_SHIFT = 9, I40E_RX_DESC_EXT_STATUS_FCOELONGB_SHIFT = 10, I40E_RX_DESC_EXT_STATUS_PELONGB_SHIFT = 11, @@ -1024,6 +1023,9 @@ struct i40e_hw_port_stats { u64 tx_size_big; /* ptc9522 */ u64 mac_short_packet_dropped; /* mspdc */ u64 checksum_error; /* xec */ + /* flow director stats */ + u64 fd_atr_match; + u64 fd_sb_match; /* EEE LPI */ u32 tx_lpi_status; u32 rx_lpi_status; diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 385a46f910d6..f5b9d2062573 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -248,9 +248,8 @@ static int i40e_config_vsi_tx_queue(struct i40e_vf *vf, u16 vsi_idx, tx_ctx.qlen = info->ring_len; tx_ctx.rdylist = le16_to_cpu(pf->vsi[vsi_idx]->info.qs_handle[0]); tx_ctx.rdylist_act = 0; - tx_ctx.head_wb_ena = 1; - tx_ctx.head_wb_addr = info->dma_ring_addr + - (info->ring_len * sizeof(struct i40e_tx_desc)); + tx_ctx.head_wb_ena = info->headwb_enabled; + tx_ctx.head_wb_addr = info->dma_headwb_addr; /* clear the context in the HMC */ ret = i40e_clear_lan_tx_queue_context(hw, pf_queue_id); @@ -2076,7 +2075,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) ret = -EIO; goto error_param; } - memcpy(vf->default_lan_addr.addr, mac, ETH_ALEN); + ether_addr_copy(vf->default_lan_addr.addr, mac); vf->pf_set_mac = true; dev_info(&pf->pdev->dev, "Reload the VF driver to make this change effective.\n"); ret = 0; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h index 89d9209ff2bd..e656ea7a7920 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h @@ -34,7 +34,7 @@ */ #define I40E_FW_API_VERSION_MAJOR 0x0001 -#define I40E_FW_API_VERSION_MINOR 0x0001 +#define I40E_FW_API_VERSION_MINOR 0x0002 #define I40E_FW_API_VERSION_A0_MINOR 0x0000 struct i40e_aq_desc { @@ -124,6 +124,7 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_get_version = 0x0001, i40e_aqc_opc_driver_version = 0x0002, i40e_aqc_opc_queue_shutdown = 0x0003, + i40e_aqc_opc_set_pf_context = 0x0004, /* resource ownership */ i40e_aqc_opc_request_resource = 0x0008, @@ -223,13 +224,15 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_get_partner_advt = 0x0616, i40e_aqc_opc_set_lb_modes = 0x0618, i40e_aqc_opc_get_phy_wol_caps = 0x0621, - i40e_aqc_opc_set_phy_reset = 0x0622, + i40e_aqc_opc_set_phy_debug = 0x0622, i40e_aqc_opc_upload_ext_phy_fm = 0x0625, /* NVM commands */ - i40e_aqc_opc_nvm_read = 0x0701, - i40e_aqc_opc_nvm_erase = 0x0702, - i40e_aqc_opc_nvm_update = 0x0703, + i40e_aqc_opc_nvm_read = 0x0701, + i40e_aqc_opc_nvm_erase = 0x0702, + i40e_aqc_opc_nvm_update = 0x0703, + i40e_aqc_opc_nvm_config_read = 0x0704, + i40e_aqc_opc_nvm_config_write = 0x0705, /* virtualization commands */ i40e_aqc_opc_send_msg_to_pf = 0x0801, @@ -271,8 +274,6 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_debug_set_mode = 0xFF01, i40e_aqc_opc_debug_read_reg = 0xFF03, i40e_aqc_opc_debug_write_reg = 0xFF04, - i40e_aqc_opc_debug_read_reg_sg = 0xFF05, - i40e_aqc_opc_debug_write_reg_sg = 0xFF06, i40e_aqc_opc_debug_modify_reg = 0xFF07, i40e_aqc_opc_debug_dump_internals = 0xFF08, i40e_aqc_opc_debug_modify_internals = 0xFF09, @@ -340,6 +341,14 @@ struct i40e_aqc_queue_shutdown { I40E_CHECK_CMD_LENGTH(i40e_aqc_queue_shutdown); +/* Set PF context (0x0004, direct) */ +struct i40e_aqc_set_pf_context { + u8 pf_id; + u8 reserved[15]; +}; + +I40E_CHECK_CMD_LENGTH(i40e_aqc_set_pf_context); + /* Request resource ownership (direct 0x0008) * Release resource ownership (direct 0x0009) */ @@ -1408,11 +1417,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_switching_comp_bw_limit); struct i40e_aqc_configure_switching_comp_ets_data { u8 reserved[4]; u8 tc_valid_bits; - u8 reserved1; + u8 seepage; +#define I40E_AQ_ETS_SEEPAGE_EN_MASK 0x1 u8 tc_strict_priority_flags; - u8 reserved2[17]; + u8 reserved1[17]; u8 tc_bw_share_credits[8]; - u8 reserved3[96]; + u8 reserved2[96]; }; /* Configure Switching Component Bandwidth Limits per Tc (indirect 0x0416) */ @@ -1529,6 +1539,8 @@ enum i40e_aq_phy_type { I40E_PHY_TYPE_XLPPI = 0x9, I40E_PHY_TYPE_40GBASE_CR4_CU = 0xA, I40E_PHY_TYPE_10GBASE_CR1_CU = 0xB, + I40E_PHY_TYPE_10GBASE_AOC = 0xC, + I40E_PHY_TYPE_40GBASE_AOC = 0xD, I40E_PHY_TYPE_100BASE_TX = 0x11, I40E_PHY_TYPE_1000BASE_T = 0x12, I40E_PHY_TYPE_10GBASE_T = 0x13, @@ -1539,7 +1551,10 @@ enum i40e_aq_phy_type { I40E_PHY_TYPE_40GBASE_CR4 = 0x18, I40E_PHY_TYPE_40GBASE_SR4 = 0x19, I40E_PHY_TYPE_40GBASE_LR4 = 0x1A, - I40E_PHY_TYPE_20GBASE_KR2 = 0x1B, + I40E_PHY_TYPE_1000BASE_SX = 0x1B, + I40E_PHY_TYPE_1000BASE_LX = 0x1C, + I40E_PHY_TYPE_1000BASE_T_OPTICAL = 0x1D, + I40E_PHY_TYPE_20GBASE_KR2 |