Commit 4bbe3f5c 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 2014-07-16

This series contains updates to i40e only.

Neerav adds support to get the port MAC address from firmware and adds
support to the ndo_get_phys_port_id() callback to provide port specific
unique ids to the netdev layer.

Jakub Kicinski provides 2 fixes, first fixes i40e to never generate a software
time stamp if the hardware time stamp is provided.  Second fixes a race
condition on queueing skb for hardware time by using a simple bit lock to
avoid race conditions and leaking skbs when multiple transmit rings try
to claim time stamping.

Paul does some general cleanup of the driver to remove unneeded spaces,
comments that are no longer valid, and break that will never get touched.

Jacob Keller adds a verbose warning message when the incorrect PF attempts
to control timestamping for a port to which it was not assigned.  The primary
intent of this message is to help debugging the reason why the SIOCSHWSTAMP
ioctl has failed and to help narrow the cause of the issue.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 48e48a70 302b4644
......@@ -134,6 +134,7 @@ enum i40e_state_t {
__I40E_EMP_RESET_REQUESTED,
__I40E_FILTER_OVERFLOW_PROMISC,
__I40E_SUSPENDED,
__I40E_PTP_TX_IN_PROGRESS,
__I40E_BAD_EEPROM,
__I40E_DOWN_REQUESTED,
};
......@@ -279,6 +280,7 @@ struct i40e_pf {
#ifdef CONFIG_I40E_VXLAN
#define I40E_FLAG_VXLAN_FILTER_SYNC (u64)(1 << 27)
#endif
#define I40E_FLAG_PORT_ID_VALID (u64)(1 << 28)
#define I40E_FLAG_DCB_CAPABLE (u64)(1 << 29)
/* tracks features that get auto disabled by errors */
......
......@@ -863,7 +863,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
/* ugh! delay while spin_lock */
udelay(delay_len);
total_delay += delay_len;
} while (total_delay < hw->aq.asq_cmd_timeout);
} while (total_delay < hw->aq.asq_cmd_timeout);
}
/* if ready, copy the desc back to temp */
......
......@@ -554,7 +554,6 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
break;
default:
return I40E_ERR_DEVICE_NOT_SUPPORTED;
break;
}
hw->phy.get_link_info = true;
......@@ -654,6 +653,31 @@ i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
return status;
}
/**
* i40e_get_port_mac_addr - get Port MAC address
* @hw: pointer to the HW structure
* @mac_addr: pointer to Port MAC address
*
* Reads the adapter's Port MAC address
**/
i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
{
struct i40e_aqc_mac_address_read_data addrs;
i40e_status status;
u16 flags = 0;
status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
if (status)
return status;
if (flags & I40E_AQC_PORT_ADDR_VALID)
memcpy(mac_addr, &addrs.port_mac, sizeof(addrs.port_mac));
else
status = I40E_ERR_INVALID_MAC_ADDR;
return status;
}
/**
* i40e_pre_tx_queue_cfg - pre tx queue configure
* @hw: pointer to the HW structure
......
......@@ -6773,13 +6773,12 @@ static int i40e_sw_init(struct i40e_pf *pf)
* maximum might end up larger than the available queues
*/
pf->rss_size_max = 0x1 << pf->hw.func_caps.rss_table_entry_width;
pf->rss_size = 1;
pf->rss_size_max = min_t(int, pf->rss_size_max,
pf->hw.func_caps.num_tx_qp);
if (pf->hw.func_caps.rss) {
pf->flags |= I40E_FLAG_RSS_ENABLED;
pf->rss_size = min_t(int, pf->rss_size_max, num_online_cpus());
} else {
pf->rss_size = 1;
}
/* MFP mode enabled */
......@@ -7018,6 +7017,22 @@ static void i40e_del_vxlan_port(struct net_device *netdev,
}
#endif
static int i40e_get_phys_port_id(struct net_device *netdev,
struct netdev_phys_port_id *ppid)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
struct i40e_hw *hw = &pf->hw;
if (!(pf->flags & I40E_FLAG_PORT_ID_VALID))
return -EOPNOTSUPP;
ppid->id_len = min_t(int, sizeof(hw->mac.port_addr), sizeof(ppid->id));
memcpy(ppid->id, hw->mac.port_addr, ppid->id_len);
return 0;
}
#ifdef HAVE_FDB_OPS
#ifdef USE_CONST_DEV_UC_CHAR
static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
......@@ -7137,6 +7152,7 @@ static const struct net_device_ops i40e_netdev_ops = {
.ndo_add_vxlan_port = i40e_add_vxlan_port,
.ndo_del_vxlan_port = i40e_del_vxlan_port,
#endif
.ndo_get_phys_port_id = i40e_get_phys_port_id,
#ifdef HAVE_FDB_OPS
.ndo_fdb_add = i40e_ndo_fdb_add,
#ifndef USE_DEFAULT_FDB_DEL_DUMP
......@@ -8686,6 +8702,9 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
dev_info(&pdev->dev, "MAC address: %pM\n", hw->mac.addr);
ether_addr_copy(hw->mac.perm_addr, hw->mac.addr);
i40e_get_port_mac_addr(hw, hw->mac.port_addr);
if (is_valid_ether_addr(hw->mac.port_addr))
pf->flags |= I40E_FLAG_PORT_ID_VALID;
pci_set_drvdata(pdev, pf);
pci_save_state(pdev);
......
......@@ -230,8 +230,8 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw);
void i40e_clear_hw(struct i40e_hw *hw);
void i40e_clear_pxe_mode(struct i40e_hw *hw);
bool i40e_get_link_status(struct i40e_hw *hw);
i40e_status i40e_get_mac_addr(struct i40e_hw *hw,
u8 *mac_addr);
i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
i40e_status i40e_validate_mac_addr(u8 *mac_addr);
void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable);
/* prototype for functions used for NVM access */
......
......@@ -314,6 +314,7 @@ void i40e_ptp_tx_hwtstamp(struct i40e_pf *pf)
skb_tstamp_tx(pf->ptp_tx_skb, &shhwtstamps);
dev_kfree_skb_any(pf->ptp_tx_skb);
pf->ptp_tx_skb = NULL;
clear_bit_unlock(__I40E_PTP_TX_IN_PROGRESS, &pf->state);
}
/**
......@@ -446,8 +447,12 @@ static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
/* Confirm that 1588 is supported on this PF. */
pf_id = (rd32(hw, I40E_PRTTSYN_CTL0) & I40E_PRTTSYN_CTL0_PF_ID_MASK) >>
I40E_PRTTSYN_CTL0_PF_ID_SHIFT;
if (hw->pf_id != pf_id)
return -EINVAL;
if (hw->pf_id != pf_id) {
dev_err(&pf->pdev->dev,
"PF %d attempted to control timestamp mode on port %d, which is owned by PF %d\n",
hw->pf_id, hw->port, pf_id);
return -EPERM;
}
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
......@@ -677,6 +682,7 @@ void i40e_ptp_stop(struct i40e_pf *pf)
if (pf->ptp_tx_skb) {
dev_kfree_skb_any(pf->ptp_tx_skb);
pf->ptp_tx_skb = NULL;
clear_bit_unlock(__I40E_PTP_TX_IN_PROGRESS, &pf->state);
}
if (pf->ptp_clock) {
......
......@@ -303,7 +303,6 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
* a specific flow spec
* @vsi: pointer to the targeted VSI
* @fd_data: the flow director data required for the FDir descriptor
* @raw_packet: the pre-allocated packet buffer for FDir
* @add: true adds a filter, false removes it
*
* Always returns -EOPNOTSUPP
......@@ -1856,7 +1855,8 @@ static int i40e_tsyn(struct i40e_ring *tx_ring, struct sk_buff *skb,
* we are not already transmitting a packet to be timestamped
*/
pf = i40e_netdev_to_pf(tx_ring->netdev);
if (pf->ptp_tx && !pf->ptp_tx_skb) {
if (pf->ptp_tx &&
!test_and_set_bit_lock(__I40E_PTP_TX_IN_PROGRESS, &pf->state)) {
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
pf->ptp_tx_skb = skb_get(skb);
} else {
......@@ -2285,13 +2285,13 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
else if (tso)
tx_flags |= I40E_TX_FLAGS_TSO;
skb_tx_timestamp(skb);
tsyn = i40e_tsyn(tx_ring, skb, tx_flags, &cd_type_cmd_tso_mss);
if (tsyn)
tx_flags |= I40E_TX_FLAGS_TSYN;
skb_tx_timestamp(skb);
/* always enable CRC insertion offload */
td_cmd |= I40E_TX_DESC_CMD_ICRC;
......
......@@ -246,6 +246,7 @@ struct i40e_mac_info {
u8 addr[ETH_ALEN];
u8 perm_addr[ETH_ALEN];
u8 san_addr[ETH_ALEN];
u8 port_addr[ETH_ALEN];
u16 max_fcoeq;
};
......
......@@ -817,7 +817,7 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
/* ugh! delay while spin_lock */
udelay(delay_len);
total_delay += delay_len;
} while (total_delay < hw->aq.asq_cmd_timeout);
} while (total_delay < hw->aq.asq_cmd_timeout);
}
/* if ready, copy the desc back to temp */
......
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