Commit a33ad9ac authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue



Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2016-01-08

This series contains updates to i40e and i40evf only.

Mitch adds a useful error message and return value when the VFs are being
reset, since there is a brief window of time when the VF cannot be
configured because they do not have a VSI to configure.  Also made a driver
change to allow the user to specify a zero MAC address for VFs, which
causes the existing MAC address to be removed and allows the VF to use a
random address (like libvirt).

Sowmini Varadhan from Oracle adds similar functionality/fix to i40e that
was added to ixgbe earlier.  The fix attempts to look up the MAC address
in the Open Firmware on systems that support it and use IDPROM on SPARC
if no OF address is found.

Anjali provides a fix the code path so that we do not call skb_set_hash()
if the feature is disabled.

Jesse removes a device ID that has never been productized and there are
no plans to use it, so just remove it.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 24759daa 56028154
......@@ -339,6 +339,7 @@ struct i40e_pf {
#define I40E_FLAG_VEB_MODE_ENABLED BIT_ULL(40)
#define I40E_FLAG_GENEVE_OFFLOAD_CAPABLE BIT_ULL(41)
#define I40E_FLAG_NO_PCI_LINK_CHECK BIT_ULL(42)
#define I40E_FLAG_PF_MAC BIT_ULL(50)
/* tracks features that get auto disabled by errors */
u64 auto_disable_flags;
......
......@@ -44,7 +44,6 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw)
switch (hw->device_id) {
case I40E_DEV_ID_SFP_XL710:
case I40E_DEV_ID_QEMU:
case I40E_DEV_ID_KX_A:
case I40E_DEV_ID_KX_B:
case I40E_DEV_ID_KX_C:
case I40E_DEV_ID_QSFP_A:
......
......@@ -30,7 +30,6 @@
/* Device IDs */
#define I40E_DEV_ID_SFP_XL710 0x1572
#define I40E_DEV_ID_QEMU 0x1574
#define I40E_DEV_ID_KX_A 0x157F
#define I40E_DEV_ID_KX_B 0x1580
#define I40E_DEV_ID_KX_C 0x1581
#define I40E_DEV_ID_QSFP_A 0x1583
......
......@@ -24,6 +24,15 @@
*
******************************************************************************/
#include <linux/etherdevice.h>
#include <linux/of_net.h>
#include <linux/pci.h>
#ifdef CONFIG_SPARC
#include <asm/idprom.h>
#include <asm/prom.h>
#endif
/* Local includes */
#include "i40e.h"
#include "i40e_diag.h"
......@@ -73,7 +82,6 @@ static int i40e_veb_get_bw_info(struct i40e_veb *veb);
static const struct pci_device_id i40e_pci_tbl[] = {
{PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_XL710), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_QEMU), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_A), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_B), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_C), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_A), 0},
......@@ -9521,6 +9529,44 @@ err_vsi:
return NULL;
}
/**
* i40e_macaddr_init - explicitly write the mac address filters.
*
* @vsi: pointer to the vsi.
* @macaddr: the MAC address
*
* This is needed when the macaddr has been obtained by other
* means than the default, e.g., from Open Firmware or IDPROM.
* Returns 0 on success, negative on failure
**/
static int i40e_macaddr_init(struct i40e_vsi *vsi, u8 *macaddr)
{
int ret;
struct i40e_aqc_add_macvlan_element_data element;
ret = i40e_aq_mac_address_write(&vsi->back->hw,
I40E_AQC_WRITE_TYPE_LAA_WOL,
macaddr, NULL);
if (ret) {
dev_info(&vsi->back->pdev->dev,
"Addr change for VSI failed: %d\n", ret);
return -EADDRNOTAVAIL;
}
memset(&element, 0, sizeof(element));
ether_addr_copy(element.mac_addr, macaddr);
element.flags = cpu_to_le16(I40E_AQC_MACVLAN_ADD_PERFECT_MATCH);
ret = i40e_aq_add_macvlan(&vsi->back->hw, vsi->seid, &element, 1, NULL);
if (ret) {
dev_info(&vsi->back->pdev->dev,
"add filter failed err %s aq_err %s\n",
i40e_stat_str(&vsi->back->hw, ret),
i40e_aq_str(&vsi->back->hw,
vsi->back->hw.aq.asq_last_status));
}
return ret;
}
/**
* i40e_vsi_setup - Set up a VSI by a given type
* @pf: board private structure
......@@ -9645,6 +9691,17 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
switch (vsi->type) {
/* setup the netdev if needed */
case I40E_VSI_MAIN:
/* Apply relevant filters if a platform-specific mac
* address was selected.
*/
if (!!(pf->flags & I40E_FLAG_PF_MAC)) {
ret = i40e_macaddr_init(vsi, pf->hw.mac.addr);
if (ret) {
dev_warn(&pf->pdev->dev,
"could not set up macaddr; err %d\n",
ret);
}
}
case I40E_VSI_VMDQ2:
case I40E_VSI_FCOE:
ret = i40e_config_netdev(vsi);
......@@ -10473,6 +10530,36 @@ static void i40e_print_features(struct i40e_pf *pf)
WARN_ON(i > INFO_STRING_LEN);
}
/**
* i40e_get_platform_mac_addr - get platform-specific MAC address
*
* @pdev: PCI device information struct
* @pf: board private structure
*
* Look up the MAC address in Open Firmware on systems that support it,
* and use IDPROM on SPARC if no OF address is found. On return, the
* I40E_FLAG_PF_MAC will be wset in pf->flags if a platform-specific value
* has been selected.
**/
static void i40e_get_platform_mac_addr(struct pci_dev *pdev, struct i40e_pf *pf)
{
struct device_node *dp = pci_device_to_OF_node(pdev);
const unsigned char *addr;
u8 *mac_addr = pf->hw.mac.addr;
pf->flags &= ~I40E_FLAG_PF_MAC;
addr = of_get_mac_address(dp);
if (addr) {
ether_addr_copy(mac_addr, addr);
pf->flags |= I40E_FLAG_PF_MAC;
#ifdef CONFIG_SPARC
} else {
ether_addr_copy(mac_addr, idprom->id_ethaddr);
pf->flags |= I40E_FLAG_PF_MAC;
#endif /* CONFIG_SPARC */
}
}
/**
* i40e_probe - Device initialization routine
* @pdev: PCI device information struct
......@@ -10683,6 +10770,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
i40e_get_mac_addr(hw, hw->mac.addr);
/* allow a platform config to override the HW addr */
i40e_get_platform_mac_addr(pdev, pf);
if (!is_valid_ether_addr(hw->mac.addr)) {
dev_info(&pdev->dev, "invalid MAC address %pM\n", hw->mac.addr);
err = -EIO;
......
......@@ -1422,31 +1422,12 @@ checksum_fail:
}
/**
* i40e_rx_hash - returns the hash value from the Rx descriptor
* @ring: descriptor ring
* @rx_desc: specific descriptor
**/
static inline u32 i40e_rx_hash(struct i40e_ring *ring,
union i40e_rx_desc *rx_desc)
{
const __le64 rss_mask =
cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
if ((ring->netdev->features & NETIF_F_RXHASH) &&
(rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask)
return le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
else
return 0;
}
/**
* i40e_ptype_to_hash - get a hash type
* i40e_ptype_to_htype - get a hash type
* @ptype: the ptype value from the descriptor
*
* Returns a hash type to be used by skb_set_hash
**/
static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
static inline enum pkt_hash_types i40e_ptype_to_htype(u8 ptype)
{
struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(ptype);
......@@ -1463,6 +1444,30 @@ static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
return PKT_HASH_TYPE_L2;
}
/**
* i40e_rx_hash - set the hash value in the skb
* @ring: descriptor ring
* @rx_desc: specific descriptor
**/
static inline void i40e_rx_hash(struct i40e_ring *ring,
union i40e_rx_desc *rx_desc,
struct sk_buff *skb,
u8 rx_ptype)
{
u32 hash;
const __le64 rss_mask =
cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
if (ring->netdev->features & NETIF_F_RXHASH)
return;
if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) {
hash = le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
skb_set_hash(skb, hash, i40e_ptype_to_htype(rx_ptype));
}
}
/**
* i40e_clean_rx_irq_ps - Reclaim resources after receive; packet split
* @rx_ring: rx ring to clean
......@@ -1612,8 +1617,8 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)
continue;
}
skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
i40e_ptype_to_hash(rx_ptype));
i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
if (unlikely(rx_status & I40E_RXD_QW1_STATUS_TSYNVALID_MASK)) {
i40e_ptp_rx_hwtstamp(vsi->back, skb, (rx_status &
I40E_RXD_QW1_STATUS_TSYNINDX_MASK) >>
......@@ -1741,8 +1746,7 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)
continue;
}
skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
i40e_ptype_to_hash(rx_ptype));
i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
if (unlikely(rx_status & I40E_RXD_QW1_STATUS_TSYNVALID_MASK)) {
i40e_ptp_rx_hwtstamp(vsi->back, skb, (rx_status &
I40E_RXD_QW1_STATUS_TSYNINDX_MASK) >>
......
......@@ -2078,15 +2078,15 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
vf = &(pf->vf[vf_id]);
vsi = pf->vsi[vf->lan_vsi_idx];
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
dev_err(&pf->pdev->dev,
"Uninitialized VF %d\n", vf_id);
ret = -EINVAL;
dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
vf_id);
ret = -EAGAIN;
goto error_param;
}
if (!is_valid_ether_addr(mac)) {
if (is_multicast_ether_addr(mac)) {
dev_err(&pf->pdev->dev,
"Invalid VF ethernet address\n");
"Invalid Ethernet address %pM for VF %d\n", mac, vf_id);
ret = -EINVAL;
goto error_param;
}
......@@ -2097,9 +2097,10 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
spin_lock_bh(&vsi->mac_filter_list_lock);
/* delete the temporary mac address */
i40e_del_filter(vsi, vf->default_lan_addr.addr,
vf->port_vlan_id ? vf->port_vlan_id : -1,
true, false);
if (!is_zero_ether_addr(vf->default_lan_addr.addr))
i40e_del_filter(vsi, vf->default_lan_addr.addr,
vf->port_vlan_id ? vf->port_vlan_id : -1,
true, false);
/* Delete all the filters for this VSI - we're going to kill it
* anyway.
......@@ -2162,8 +2163,9 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
vf = &(pf->vf[vf_id]);
vsi = pf->vsi[vf->lan_vsi_idx];
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
dev_err(&pf->pdev->dev, "Uninitialized VF %d\n", vf_id);
ret = -EINVAL;
dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
vf_id);
ret = -EAGAIN;
goto error_pvid;
}
......@@ -2282,8 +2284,9 @@ int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
vf = &(pf->vf[vf_id]);
vsi = pf->vsi[vf->lan_vsi_idx];
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
dev_err(&pf->pdev->dev, "Uninitialized VF %d.\n", vf_id);
ret = -EINVAL;
dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
vf_id);
ret = -EAGAIN;
goto error;
}
......@@ -2356,8 +2359,9 @@ int i40e_ndo_get_vf_config(struct net_device *netdev,
/* first vsi is always the LAN vsi */
vsi = pf->vsi[vf->lan_vsi_idx];
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
dev_err(&pf->pdev->dev, "Uninitialized VF %d\n", vf_id);
ret = -EINVAL;
dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
vf_id);
ret = -EAGAIN;
goto error_param;
}
......@@ -2472,6 +2476,12 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable)
}
vf = &(pf->vf[vf_id]);
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
vf_id);
ret = -EAGAIN;
goto out;
}
if (enable == vf->spoofchk)
goto out;
......
......@@ -44,7 +44,6 @@ i40e_status i40e_set_mac_type(struct i40e_hw *hw)
switch (hw->device_id) {
case I40E_DEV_ID_SFP_XL710:
case I40E_DEV_ID_QEMU:
case I40E_DEV_ID_KX_A:
case I40E_DEV_ID_KX_B:
case I40E_DEV_ID_KX_C:
case I40E_DEV_ID_QSFP_A:
......
......@@ -30,7 +30,6 @@
/* Device IDs */
#define I40E_DEV_ID_SFP_XL710 0x1572
#define I40E_DEV_ID_QEMU 0x1574
#define I40E_DEV_ID_KX_A 0x157F
#define I40E_DEV_ID_KX_B 0x1580
#define I40E_DEV_ID_KX_C 0x1581
#define I40E_DEV_ID_QSFP_A 0x1583
......
......@@ -886,31 +886,12 @@ checksum_fail:
}
/**
* i40e_rx_hash - returns the hash value from the Rx descriptor
* @ring: descriptor ring
* @rx_desc: specific descriptor
**/
static inline u32 i40e_rx_hash(struct i40e_ring *ring,
union i40e_rx_desc *rx_desc)
{
const __le64 rss_mask =
cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
if ((ring->netdev->features & NETIF_F_RXHASH) &&
(rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask)
return le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
else
return 0;
}
/**
* i40e_ptype_to_hash - get a hash type
* i40e_ptype_to_htype - get a hash type
* @ptype: the ptype value from the descriptor
*
* Returns a hash type to be used by skb_set_hash
**/
static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
static inline enum pkt_hash_types i40e_ptype_to_htype(u8 ptype)
{
struct i40e_rx_ptype_decoded decoded = decode_rx_desc_ptype(ptype);
......@@ -927,6 +908,30 @@ static inline enum pkt_hash_types i40e_ptype_to_hash(u8 ptype)
return PKT_HASH_TYPE_L2;
}
/**
* i40e_rx_hash - set the hash value in the skb
* @ring: descriptor ring
* @rx_desc: specific descriptor
**/
static inline void i40e_rx_hash(struct i40e_ring *ring,
union i40e_rx_desc *rx_desc,
struct sk_buff *skb,
u8 rx_ptype)
{
u32 hash;
const __le64 rss_mask =
cpu_to_le64((u64)I40E_RX_DESC_FLTSTAT_RSS_HASH <<
I40E_RX_DESC_STATUS_FLTSTAT_SHIFT);
if (ring->netdev->features & NETIF_F_RXHASH)
return;
if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) {
hash = le32_to_cpu(rx_desc->wb.qword0.hi_dword.rss);
skb_set_hash(skb, hash, i40e_ptype_to_htype(rx_ptype));
}
}
/**
* i40e_clean_rx_irq_ps - Reclaim resources after receive; packet split
* @rx_ring: rx ring to clean
......@@ -1068,8 +1073,8 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)
continue;
}
skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
i40e_ptype_to_hash(rx_ptype));
i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
/* probably a little skewed due to removing CRC */
total_rx_bytes += skb->len;
total_rx_packets++;
......@@ -1185,8 +1190,7 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)
continue;
}
skb_set_hash(skb, i40e_rx_hash(rx_ring, rx_desc),
i40e_ptype_to_hash(rx_ptype));
i40e_rx_hash(rx_ring, rx_desc, skb, rx_ptype);
/* probably a little skewed due to removing CRC */
total_rx_bytes += skb->len;
total_rx_packets++;
......
Supports Markdown
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