aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-07-17 02:52:18 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-17 02:52:18 -0400
commit4bbe3f5c7174e989989c04d41e6640ac0b944dac (patch)
treee51236ab425b90d1b0525b52b4186b1485c76e3b /drivers/net/ethernet
parent48e48a70c08a8a68f8697f8b30cb83775bda8001 (diff)
parent302b46449e2918a30b3f98a54653972d2ad0f072 (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-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: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.c2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c26
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c23
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_prototype.h4
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ptp.c10
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c8
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_type.h1
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.c2
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 {
134 __I40E_EMP_RESET_REQUESTED, 134 __I40E_EMP_RESET_REQUESTED,
135 __I40E_FILTER_OVERFLOW_PROMISC, 135 __I40E_FILTER_OVERFLOW_PROMISC,
136 __I40E_SUSPENDED, 136 __I40E_SUSPENDED,
137 __I40E_PTP_TX_IN_PROGRESS,
137 __I40E_BAD_EEPROM, 138 __I40E_BAD_EEPROM,
138 __I40E_DOWN_REQUESTED, 139 __I40E_DOWN_REQUESTED,
139}; 140};
@@ -279,6 +280,7 @@ struct i40e_pf {
279#ifdef CONFIG_I40E_VXLAN 280#ifdef CONFIG_I40E_VXLAN
280#define I40E_FLAG_VXLAN_FILTER_SYNC (u64)(1 << 27) 281#define I40E_FLAG_VXLAN_FILTER_SYNC (u64)(1 << 27)
281#endif 282#endif
283#define I40E_FLAG_PORT_ID_VALID (u64)(1 << 28)
282#define I40E_FLAG_DCB_CAPABLE (u64)(1 << 29) 284#define I40E_FLAG_DCB_CAPABLE (u64)(1 << 29)
283 285
284 /* tracks features that get auto disabled by errors */ 286 /* 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,
863 /* ugh! delay while spin_lock */ 863 /* ugh! delay while spin_lock */
864 udelay(delay_len); 864 udelay(delay_len);
865 total_delay += delay_len; 865 total_delay += delay_len;
866 } while (total_delay < hw->aq.asq_cmd_timeout); 866 } while (total_delay < hw->aq.asq_cmd_timeout);
867 } 867 }
868 868
869 /* if ready, copy the desc back to temp */ 869 /* 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)
554 break; 554 break;
555 default: 555 default:
556 return I40E_ERR_DEVICE_NOT_SUPPORTED; 556 return I40E_ERR_DEVICE_NOT_SUPPORTED;
557 break;
558 } 557 }
559 558
560 hw->phy.get_link_info = true; 559 hw->phy.get_link_info = true;
@@ -655,6 +654,31 @@ i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
655} 654}
656 655
657/** 656/**
657 * i40e_get_port_mac_addr - get Port MAC address
658 * @hw: pointer to the HW structure
659 * @mac_addr: pointer to Port MAC address
660 *
661 * Reads the adapter's Port MAC address
662 **/
663i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
664{
665 struct i40e_aqc_mac_address_read_data addrs;
666 i40e_status status;
667 u16 flags = 0;
668
669 status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
670 if (status)
671 return status;
672
673 if (flags & I40E_AQC_PORT_ADDR_VALID)
674 memcpy(mac_addr, &addrs.port_mac, sizeof(addrs.port_mac));
675 else
676 status = I40E_ERR_INVALID_MAC_ADDR;
677
678 return status;
679}
680
681/**
658 * i40e_pre_tx_queue_cfg - pre tx queue configure 682 * i40e_pre_tx_queue_cfg - pre tx queue configure
659 * @hw: pointer to the HW structure 683 * @hw: pointer to the HW structure
660 * @queue: target pf queue index 684 * @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)
6773 * maximum might end up larger than the available queues 6773 * maximum might end up larger than the available queues
6774 */ 6774 */
6775 pf->rss_size_max = 0x1 << pf->hw.func_caps.rss_table_entry_width; 6775 pf->rss_size_max = 0x1 << pf->hw.func_caps.rss_table_entry_width;
6776 pf->rss_size = 1;
6776 pf->rss_size_max = min_t(int, pf->rss_size_max, 6777 pf->rss_size_max = min_t(int, pf->rss_size_max,
6777 pf->hw.func_caps.num_tx_qp); 6778 pf->hw.func_caps.num_tx_qp);
6778 if (pf->hw.func_caps.rss) { 6779 if (pf->hw.func_caps.rss) {
6779 pf->flags |= I40E_FLAG_RSS_ENABLED; 6780 pf->flags |= I40E_FLAG_RSS_ENABLED;
6780 pf->rss_size = min_t(int, pf->rss_size_max, num_online_cpus()); 6781 pf->rss_size = min_t(int, pf->rss_size_max, num_online_cpus());
6781 } else {
6782 pf->rss_size = 1;
6783 } 6782 }
6784 6783
6785 /* MFP mode enabled */ 6784 /* MFP mode enabled */
@@ -7018,6 +7017,22 @@ static void i40e_del_vxlan_port(struct net_device *netdev,
7018} 7017}
7019 7018
7020#endif 7019#endif
7020static int i40e_get_phys_port_id(struct net_device *netdev,
7021 struct netdev_phys_port_id *ppid)
7022{
7023 struct i40e_netdev_priv *np = netdev_priv(netdev);
7024 struct i40e_pf *pf = np->vsi->back;
7025 struct i40e_hw *hw = &pf->hw;
7026
7027 if (!(pf->flags & I40E_FLAG_PORT_ID_VALID))
7028 return -EOPNOTSUPP;
7029
7030 ppid->id_len = min_t(int, sizeof(hw->mac.port_addr), sizeof(ppid->id));
7031 memcpy(ppid->id, hw->mac.port_addr, ppid->id_len);
7032
7033 return 0;
7034}
7035
7021#ifdef HAVE_FDB_OPS 7036#ifdef HAVE_FDB_OPS
7022#ifdef USE_CONST_DEV_UC_CHAR 7037#ifdef USE_CONST_DEV_UC_CHAR
7023static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], 7038static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
@@ -7137,6 +7152,7 @@ static const struct net_device_ops i40e_netdev_ops = {
7137 .ndo_add_vxlan_port = i40e_add_vxlan_port, 7152 .ndo_add_vxlan_port = i40e_add_vxlan_port,
7138 .ndo_del_vxlan_port = i40e_del_vxlan_port, 7153 .ndo_del_vxlan_port = i40e_del_vxlan_port,
7139#endif 7154#endif
7155 .ndo_get_phys_port_id = i40e_get_phys_port_id,
7140#ifdef HAVE_FDB_OPS 7156#ifdef HAVE_FDB_OPS
7141 .ndo_fdb_add = i40e_ndo_fdb_add, 7157 .ndo_fdb_add = i40e_ndo_fdb_add,
7142#ifndef USE_DEFAULT_FDB_DEL_DUMP 7158#ifndef USE_DEFAULT_FDB_DEL_DUMP
@@ -8686,6 +8702,9 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
8686 } 8702 }
8687 dev_info(&pdev->dev, "MAC address: %pM\n", hw->mac.addr); 8703 dev_info(&pdev->dev, "MAC address: %pM\n", hw->mac.addr);
8688 ether_addr_copy(hw->mac.perm_addr, hw->mac.addr); 8704 ether_addr_copy(hw->mac.perm_addr, hw->mac.addr);
8705 i40e_get_port_mac_addr(hw, hw->mac.port_addr);
8706 if (is_valid_ether_addr(hw->mac.port_addr))
8707 pf->flags |= I40E_FLAG_PORT_ID_VALID;
8689 8708
8690 pci_set_drvdata(pdev, pf); 8709 pci_set_drvdata(pdev, pf);
8691 pci_save_state(pdev); 8710 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);
230void i40e_clear_hw(struct i40e_hw *hw); 230void i40e_clear_hw(struct i40e_hw *hw);
231void i40e_clear_pxe_mode(struct i40e_hw *hw); 231void i40e_clear_pxe_mode(struct i40e_hw *hw);
232bool i40e_get_link_status(struct i40e_hw *hw); 232bool i40e_get_link_status(struct i40e_hw *hw);
233i40e_status i40e_get_mac_addr(struct i40e_hw *hw, 233i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
234 u8 *mac_addr); 234i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
235i40e_status i40e_validate_mac_addr(u8 *mac_addr); 235i40e_status i40e_validate_mac_addr(u8 *mac_addr);
236void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable); 236void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable);
237/* prototype for functions used for NVM access */ 237/* 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)
314 skb_tstamp_tx(pf->ptp_tx_skb, &shhwtstamps); 314 skb_tstamp_tx(pf->ptp_tx_skb, &shhwtstamps);
315 dev_kfree_skb_any(pf->ptp_tx_skb); 315 dev_kfree_skb_any(pf->ptp_tx_skb);
316 pf->ptp_tx_skb = NULL; 316 pf->ptp_tx_skb = NULL;
317 clear_bit_unlock(__I40E_PTP_TX_IN_PROGRESS, &pf->state);
317} 318}
318 319
319/** 320/**
@@ -446,8 +447,12 @@ static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
446 /* Confirm that 1588 is supported on this PF. */ 447 /* Confirm that 1588 is supported on this PF. */
447 pf_id = (rd32(hw, I40E_PRTTSYN_CTL0) & I40E_PRTTSYN_CTL0_PF_ID_MASK) >> 448 pf_id = (rd32(hw, I40E_PRTTSYN_CTL0) & I40E_PRTTSYN_CTL0_PF_ID_MASK) >>
448 I40E_PRTTSYN_CTL0_PF_ID_SHIFT; 449 I40E_PRTTSYN_CTL0_PF_ID_SHIFT;
449 if (hw->pf_id != pf_id) 450 if (hw->pf_id != pf_id) {
450 return -EINVAL; 451 dev_err(&pf->pdev->dev,
452 "PF %d attempted to control timestamp mode on port %d, which is owned by PF %d\n",
453 hw->pf_id, hw->port, pf_id);
454 return -EPERM;
455 }
451 456
452 switch (config->tx_type) { 457 switch (config->tx_type) {
453 case HWTSTAMP_TX_OFF: 458 case HWTSTAMP_TX_OFF:
@@ -677,6 +682,7 @@ void i40e_ptp_stop(struct i40e_pf *pf)
677 if (pf->ptp_tx_skb) { 682 if (pf->ptp_tx_skb) {
678 dev_kfree_skb_any(pf->ptp_tx_skb); 683 dev_kfree_skb_any(pf->ptp_tx_skb);
679 pf->ptp_tx_skb = NULL; 684 pf->ptp_tx_skb = NULL;
685 clear_bit_unlock(__I40E_PTP_TX_IN_PROGRESS, &pf->state);
680 } 686 }
681 687
682 if (pf->ptp_clock) { 688 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,
303 * a specific flow spec 303 * a specific flow spec
304 * @vsi: pointer to the targeted VSI 304 * @vsi: pointer to the targeted VSI
305 * @fd_data: the flow director data required for the FDir descriptor 305 * @fd_data: the flow director data required for the FDir descriptor
306 * @raw_packet: the pre-allocated packet buffer for FDir
307 * @add: true adds a filter, false removes it 306 * @add: true adds a filter, false removes it
308 * 307 *
309 * Always returns -EOPNOTSUPP 308 * Always returns -EOPNOTSUPP
@@ -1856,7 +1855,8 @@ static int i40e_tsyn(struct i40e_ring *tx_ring, struct sk_buff *skb,
1856 * we are not already transmitting a packet to be timestamped 1855 * we are not already transmitting a packet to be timestamped
1857 */ 1856 */
1858 pf = i40e_netdev_to_pf(tx_ring->netdev); 1857 pf = i40e_netdev_to_pf(tx_ring->netdev);
1859 if (pf->ptp_tx && !pf->ptp_tx_skb) { 1858 if (pf->ptp_tx &&
1859 !test_and_set_bit_lock(__I40E_PTP_TX_IN_PROGRESS, &pf->state)) {
1860 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 1860 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
1861 pf->ptp_tx_skb = skb_get(skb); 1861 pf->ptp_tx_skb = skb_get(skb);
1862 } else { 1862 } else {
@@ -2285,13 +2285,13 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
2285 else if (tso) 2285 else if (tso)
2286 tx_flags |= I40E_TX_FLAGS_TSO; 2286 tx_flags |= I40E_TX_FLAGS_TSO;
2287 2287
2288 skb_tx_timestamp(skb);
2289
2290 tsyn = i40e_tsyn(tx_ring, skb, tx_flags, &cd_type_cmd_tso_mss); 2288 tsyn = i40e_tsyn(tx_ring, skb, tx_flags, &cd_type_cmd_tso_mss);
2291 2289
2292 if (tsyn) 2290 if (tsyn)
2293 tx_flags |= I40E_TX_FLAGS_TSYN; 2291 tx_flags |= I40E_TX_FLAGS_TSYN;
2294 2292
2293 skb_tx_timestamp(skb);
2294
2295 /* always enable CRC insertion offload */ 2295 /* always enable CRC insertion offload */
2296 td_cmd |= I40E_TX_DESC_CMD_ICRC; 2296 td_cmd |= I40E_TX_DESC_CMD_ICRC;
2297 2297
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 {
246 u8 addr[ETH_ALEN]; 246 u8 addr[ETH_ALEN];
247 u8 perm_addr[ETH_ALEN]; 247 u8 perm_addr[ETH_ALEN];
248 u8 san_addr[ETH_ALEN]; 248 u8 san_addr[ETH_ALEN];
249 u8 port_addr[ETH_ALEN];
249 u16 max_fcoeq; 250 u16 max_fcoeq;
250}; 251};
251 252
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,
817 /* ugh! delay while spin_lock */ 817 /* ugh! delay while spin_lock */
818 udelay(delay_len); 818 udelay(delay_len);
819 total_delay += delay_len; 819 total_delay += delay_len;
820 } while (total_delay < hw->aq.asq_cmd_timeout); 820 } while (total_delay < hw->aq.asq_cmd_timeout);
821 } 821 }
822 822
823 /* if ready, copy the desc back to temp */ 823 /* if ready, copy the desc back to temp */