diff options
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_adminq.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_common.c | 26 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_main.c | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_prototype.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_ptp.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_type.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40evf/i40e_adminq.c | 2 |
9 files changed, 65 insertions, 13 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 0fbb32a8ad42..29cd81ae29f4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -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 */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c index 2708bcdddd41..0e551f281d59 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c @@ -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 */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index bf808d4cb7b8..c65f4e8e6cee 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -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; @@ -655,6 +654,31 @@ i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr) } /** + * 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 * @queue: target pf queue index diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 2899f783ee1d..c34e39009a8f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -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); diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h index b6849fb47db7..9383f08ff4e3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h +++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h @@ -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 */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c index c364781c8160..bb7fe98b3a6c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c @@ -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) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 2c686e2dfe1d..989866af26e5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -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; diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index 380eb53a83b3..1fcf2205ffe6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -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; }; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c index cc4b6db10b04..8330744b02f1 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c @@ -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 */ |