diff options
Diffstat (limited to 'drivers/net/igb')
-rw-r--r-- | drivers/net/igb/e1000_82575.c | 33 | ||||
-rw-r--r-- | drivers/net/igb/e1000_82575.h | 9 | ||||
-rw-r--r-- | drivers/net/igb/e1000_defines.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/e1000_hw.h | 17 | ||||
-rw-r--r-- | drivers/net/igb/igb.h | 2 | ||||
-rw-r--r-- | drivers/net/igb/igb_ethtool.c | 50 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 123 |
7 files changed, 151 insertions, 84 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 0bc990ec4a8e..430631f49d9d 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -105,6 +105,12 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) case E1000_DEV_ID_82580_COPPER_DUAL: mac->type = e1000_82580; break; + case E1000_DEV_ID_I350_COPPER: + case E1000_DEV_ID_I350_FIBER: + case E1000_DEV_ID_I350_SERDES: + case E1000_DEV_ID_I350_SGMII: + mac->type = e1000_i350; + break; default: return -E1000_ERR_MAC_INIT; break; @@ -154,8 +160,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->rar_entry_count = E1000_RAR_ENTRIES_82576; if (mac->type == e1000_82580) mac->rar_entry_count = E1000_RAR_ENTRIES_82580; + if (mac->type == e1000_i350) + mac->rar_entry_count = E1000_RAR_ENTRIES_I350; /* reset */ - if (mac->type == e1000_82580) + if (mac->type >= e1000_82580) mac->ops.reset_hw = igb_reset_hw_82580; else mac->ops.reset_hw = igb_reset_hw_82575; @@ -226,7 +234,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) phy->ops.reset = igb_phy_hw_reset_sgmii_82575; phy->ops.read_reg = igb_read_phy_reg_sgmii_82575; phy->ops.write_reg = igb_write_phy_reg_sgmii_82575; - } else if (hw->mac.type == e1000_82580) { + } else if (hw->mac.type >= e1000_82580) { phy->ops.reset = igb_phy_hw_reset; phy->ops.read_reg = igb_read_phy_reg_82580; phy->ops.write_reg = igb_write_phy_reg_82580; @@ -262,6 +270,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state; break; case I82580_I_PHY_ID: + case I350_I_PHY_ID: phy->type = e1000_phy_82580; phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_82580; phy->ops.get_cable_length = igb_get_cable_length_82580; @@ -1446,7 +1455,6 @@ void igb_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable) **/ static s32 igb_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data) { - u32 mdicnfg = 0; s32 ret_val; @@ -1454,15 +1462,6 @@ static s32 igb_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data) if (ret_val) goto out; - /* - * We config the phy address in MDICNFG register now. Same bits - * as before. The values in MDIC can be written but will be - * ignored. This allows us to call the old function after - * configuring the PHY address in the new register - */ - mdicnfg = (hw->phy.addr << E1000_MDIC_PHY_SHIFT); - wr32(E1000_MDICNFG, mdicnfg); - ret_val = igb_read_phy_reg_mdic(hw, offset, data); hw->phy.ops.release(hw); @@ -1481,7 +1480,6 @@ out: **/ static s32 igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data) { - u32 mdicnfg = 0; s32 ret_val; @@ -1489,15 +1487,6 @@ static s32 igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data) if (ret_val) goto out; - /* - * We config the phy address in MDICNFG register now. Same bits - * as before. The values in MDIC can be written but will be - * ignored. This allows us to call the old function after - * configuring the PHY address in the new register - */ - mdicnfg = (hw->phy.addr << E1000_MDIC_PHY_SHIFT); - wr32(E1000_MDICNFG, mdicnfg); - ret_val = igb_write_phy_reg_mdic(hw, offset, data); hw->phy.ops.release(hw); diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index fbe1c99c193c..cbd1e1259e4d 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h @@ -38,9 +38,10 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw); (ID_LED_DEF1_DEF2 << 4) | \ (ID_LED_OFF1_ON2)) -#define E1000_RAR_ENTRIES_82575 16 -#define E1000_RAR_ENTRIES_82576 24 -#define E1000_RAR_ENTRIES_82580 24 +#define E1000_RAR_ENTRIES_82575 16 +#define E1000_RAR_ENTRIES_82576 24 +#define E1000_RAR_ENTRIES_82580 24 +#define E1000_RAR_ENTRIES_I350 32 #define E1000_SW_SYNCH_MB 0x00000100 #define E1000_STAT_DEV_RST_SET 0x00100000 @@ -52,6 +53,7 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw); #define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 #define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 #define E1000_SRRCTL_DROP_EN 0x80000000 +#define E1000_SRRCTL_TIMESTAMP 0x40000000 #define E1000_MRQC_ENABLE_RSS_4Q 0x00000002 #define E1000_MRQC_ENABLE_VMDQ 0x00000003 @@ -108,6 +110,7 @@ union e1000_adv_rx_desc { #define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0 #define E1000_RXDADV_HDRBUFLEN_SHIFT 5 #define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */ +#define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */ /* Transmit Descriptor - Advanced */ union e1000_adv_tx_desc { diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index fe6cf1b696c7..31d24e0e76de 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -629,6 +629,7 @@ #define M88E1111_I_PHY_ID 0x01410CC0 #define IGP03E1000_E_PHY_ID 0x02A80390 #define I82580_I_PHY_ID 0x015403A0 +#define I350_I_PHY_ID 0x015403B0 #define M88_VENDOR 0x0141 /* M88E1000 Specific Registers */ diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index 82a533f5192a..cb8db78b1a05 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -31,6 +31,7 @@ #include <linux/types.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/netdevice.h> #include "e1000_regs.h" #include "e1000_defines.h" @@ -53,6 +54,10 @@ struct e1000_hw; #define E1000_DEV_ID_82580_SERDES 0x1510 #define E1000_DEV_ID_82580_SGMII 0x1511 #define E1000_DEV_ID_82580_COPPER_DUAL 0x1516 +#define E1000_DEV_ID_I350_COPPER 0x1521 +#define E1000_DEV_ID_I350_FIBER 0x1522 +#define E1000_DEV_ID_I350_SERDES 0x1523 +#define E1000_DEV_ID_I350_SGMII 0x1524 #define E1000_REVISION_2 2 #define E1000_REVISION_4 4 @@ -72,6 +77,7 @@ enum e1000_mac_type { e1000_82575, e1000_82576, e1000_82580, + e1000_i350, e1000_num_macs /* List is 1-based, so subtract 1 for true count. */ }; @@ -502,14 +508,11 @@ struct e1000_hw { u8 revision_id; }; -#ifdef DEBUG -extern char *igb_get_hw_dev_name(struct e1000_hw *hw); +extern struct net_device *igb_get_hw_dev(struct e1000_hw *hw); #define hw_dbg(format, arg...) \ - printk(KERN_DEBUG "%s: " format, igb_get_hw_dev_name(hw), ##arg) -#else -#define hw_dbg(format, arg...) -#endif -#endif + netdev_dbg(igb_get_hw_dev(hw), format, ##arg) + /* These functions must be implemented by drivers */ s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); +#endif /* _E1000_HW_H_ */ diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 3b772b822a5d..7d288ccca1ca 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -107,6 +107,7 @@ struct vf_data_storage { #define MAXIMUM_ETHERNET_VLAN_SIZE 1522 /* Supported Rx Buffer Sizes */ +#define IGB_RXBUFFER_64 64 /* Used for packet split */ #define IGB_RXBUFFER_128 128 /* Used for packet split */ #define IGB_RXBUFFER_1024 1024 #define IGB_RXBUFFER_2048 2048 @@ -323,6 +324,7 @@ struct igb_adapter { #define IGB_82576_TSYNC_SHIFT 19 #define IGB_82580_TSYNC_SHIFT 24 +#define IGB_TS_HDR_LEN 16 enum e1000_state_t { __IGB_TESTING, __IGB_RESETTING, diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index a4cead12fd98..1d4ee418226d 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -901,6 +901,49 @@ struct igb_reg_test { #define TABLE64_TEST_LO 5 #define TABLE64_TEST_HI 6 +/* i350 reg test */ +static struct igb_reg_test reg_test_i350[] = { + { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF }, + { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF }, + { E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFF0000, 0xFFFF0000 }, + { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, + { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, + { E1000_RDBAL(4), 0x40, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, + { E1000_RDBAH(4), 0x40, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_RDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, + /* RDH is read-only for i350, only test RDT. */ + { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { E1000_RDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 }, + { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF }, + { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, + { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, + { E1000_TDBAL(4), 0x40, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, + { E1000_TDBAH(4), 0x40, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_TDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, + { E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { E1000_TDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, + { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, + { E1000_RA, 0, 16, TABLE64_TEST_LO, + 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_RA, 0, 16, TABLE64_TEST_HI, + 0xC3FFFFFF, 0xFFFFFFFF }, + { E1000_RA2, 0, 16, TABLE64_TEST_LO, + 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_RA2, 0, 16, TABLE64_TEST_HI, + 0xC3FFFFFF, 0xFFFFFFFF }, + { E1000_MTA, 0, 128, TABLE32_TEST, + 0xFFFFFFFF, 0xFFFFFFFF }, + { 0, 0, 0, 0 } +}; + /* 82580 reg test */ static struct igb_reg_test reg_test_82580[] = { { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, @@ -1076,6 +1119,10 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data) u32 i, toggle; switch (adapter->hw.mac.type) { + case e1000_i350: + test = reg_test_i350; + toggle = 0x7FEFF3FF; + break; case e1000_82580: test = reg_test_82580; toggle = 0x7FEFF3FF; @@ -1237,6 +1284,9 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) case e1000_82580: ics_mask = 0x77DCFED5; break; + case e1000_i350: + ics_mask = 0x77DCFED5; + break; default: ics_mask = 0x7FFFFFFF; break; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 01c65c7447e1..2745e17fd021 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -61,6 +61,10 @@ static const struct e1000_info *igb_info_tbl[] = { }; static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_COPPER), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_FIBER), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SERDES), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SGMII), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_FIBER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES), board_82575 }, @@ -222,43 +226,17 @@ static cycle_t igb_read_clock(const struct cyclecounter *tc) return stamp; } -#ifdef DEBUG /** - * igb_get_hw_dev_name - return device name string + * igb_get_hw_dev - return device * used by hardware layer to print debugging information **/ -char *igb_get_hw_dev_name(struct e1000_hw *hw) +struct net_device *igb_get_hw_dev(struct e1000_hw *hw) { struct igb_adapter *adapter = hw->back; - return adapter->netdev->name; + return adapter->netdev; } /** - * igb_get_time_str - format current NIC and system time as string - */ -static char *igb_get_time_str(struct igb_adapter *adapter, - char buffer[160]) -{ - cycle_t hw = adapter->cycles.read(&adapter->cycles); - struct timespec nic = ns_to_timespec(timecounter_read(&adapter->clock)); - struct timespec sys; - struct timespec delta; - getnstimeofday(&sys); - - delta = timespec_sub(nic, sys); - - sprintf(buffer, - "HW %llu, NIC %ld.%09lus, SYS %ld.%09lus, NIC-SYS %lds + %09luns", - hw, - (long)nic.tv_sec, nic.tv_nsec, - (long)sys.tv_sec, sys.tv_nsec, - (long)delta.tv_sec, delta.tv_nsec); - - return buffer; -} -#endif - -/** * igb_init_module - Driver Registration Routine * * igb_init_module is the first routine called when the driver is @@ -327,6 +305,7 @@ static void igb_cache_ring_register(struct igb_adapter *adapter) } case e1000_82575: case e1000_82580: + case e1000_i350: default: for (; i < adapter->num_rx_queues; i++) adapter->rx_ring[i]->reg_idx = rbase_offset + i; @@ -470,6 +449,7 @@ static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector) q_vector->eims_value = 1 << msix_vector; break; case e1000_82580: + case e1000_i350: /* 82580 uses the same table-based approach as 82576 but has fewer entries as a result we carry over for queues greater than 4. */ if (rx_queue > IGB_N0_QUEUE) { @@ -550,6 +530,7 @@ static void igb_configure_msix(struct igb_adapter *adapter) case e1000_82576: case e1000_82580: + case e1000_i350: /* Turn on MSI-X capability first, or our settings * won't stick. And it will take days to debug. */ wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE | @@ -1252,6 +1233,7 @@ void igb_reset(struct igb_adapter *adapter) * To take effect CTRL.RST is required. */ switch (mac->type) { + case e1000_i350: case e1000_82580: pba = rd32(E1000_RXPBS); pba = igb_rxpbs_adjust_82580(pba); @@ -1824,6 +1806,7 @@ static void igb_init_hw_timer(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; switch (hw->mac.type) { + case e1000_i350: case e1000_82580: memset(&adapter->cycles, 0, sizeof(adapter->cycles)); adapter->cycles.read = igb_read_clock; @@ -2337,6 +2320,7 @@ static void igb_setup_mrqc(struct igb_adapter *adapter) if (adapter->vfs_allocated_count) { /* 82575 and 82576 supports 2 RSS queues for VMDq */ switch (hw->mac.type) { + case e1000_i350: case e1000_82580: num_rx_queues = 1; shift = 0; @@ -2588,6 +2572,8 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, E1000_SRRCTL_BSIZEPKT_SHIFT; srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF; } + if (hw->mac.type == e1000_82580) + srrctl |= E1000_SRRCTL_TIMESTAMP; /* Only set Drop Enable if we are supporting multiple queues */ if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1) srrctl |= E1000_SRRCTL_DROP_EN; @@ -2874,7 +2860,7 @@ static int igb_write_mc_addr_list(struct net_device *netdev) { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - struct dev_mc_list *mc_ptr; + struct netdev_hw_addr *ha; u8 *mta_list; int i; @@ -2891,8 +2877,8 @@ static int igb_write_mc_addr_list(struct net_device *netdev) /* The shared function expects a packed array of only addresses. */ i = 0; - netdev_for_each_mc_addr(mc_ptr, netdev) - memcpy(mta_list + (i++ * ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN); + netdev_for_each_mc_addr(ha, netdev) + memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN); igb_update_mc_addr_list(hw, mta_list, i); kfree(mta_list); @@ -3918,6 +3904,9 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu) * i.e. RXBUFFER_2048 --> size-4096 slab */ + if (adapter->hw.mac.type == e1000_82580) + max_frame += IGB_TS_HDR_LEN; + if (max_frame <= IGB_RXBUFFER_1024) rx_buffer_len = IGB_RXBUFFER_1024; else if (max_frame <= MAXIMUM_ETHERNET_VLAN_SIZE) @@ -3925,6 +3914,14 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu) else rx_buffer_len = IGB_RXBUFFER_128; + if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN + IGB_TS_HDR_LEN) || + (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE + IGB_TS_HDR_LEN)) + rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE + IGB_TS_HDR_LEN; + + if ((adapter->hw.mac.type == e1000_82580) && + (rx_buffer_len == IGB_RXBUFFER_128)) + rx_buffer_len += IGB_RXBUFFER_64; + if (netif_running(netdev)) igb_down(adapter); @@ -5141,7 +5138,7 @@ static inline void igb_rx_checksum_adv(struct igb_ring *ring, dev_dbg(&ring->pdev->dev, "cksum success: bits %08X\n", status_err); } -static inline void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, +static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, struct sk_buff *skb) { struct igb_adapter *adapter = q_vector->adapter; @@ -5159,13 +5156,18 @@ static inline void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, * If nothing went wrong, then it should have a skb_shared_tx that we * can turn into a skb_shared_hwtstamps. */ - if (likely(!(staterr & E1000_RXDADV_STAT_TS))) - return; - if (!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) - return; + if (staterr & E1000_RXDADV_STAT_TSIP) { + u32 *stamp = (u32 *)skb->data; + regval = le32_to_cpu(*(stamp + 2)); + regval |= (u64)le32_to_cpu(*(stamp + 3)) << 32; + skb_pull(skb, IGB_TS_HDR_LEN); + } else { + if(!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) + return; - regval = rd32(E1000_RXSTMPL); - regval |= (u64)rd32(E1000_RXSTMPH) << 32; + regval = rd32(E1000_RXSTMPL); + regval |= (u64)rd32(E1000_RXSTMPH) << 32; + } igb_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); } @@ -5273,7 +5275,8 @@ send_up: goto next_desc; } - igb_rx_hwtstamp(q_vector, staterr, skb); + if (staterr & (E1000_RXDADV_STAT_TSIP | E1000_RXDADV_STAT_TS)) + igb_rx_hwtstamp(q_vector, staterr, skb); total_bytes += skb->len; total_packets++; @@ -5553,6 +5556,16 @@ static int igb_hwtstamp_ioctl(struct net_device *netdev, return 0; } + /* + * Per-packet timestamping only works if all packets are + * timestamped, so enable timestamping in all packets as + * long as one rx filter was configured. + */ + if ((hw->mac.type == e1000_82580) && tsync_rx_ctl) { + tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED; + tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL; + } + /* enable/disable TX */ regval = rd32(E1000_TSYNCTXCTL); regval &= ~E1000_TSYNCTXCTL_ENABLED; @@ -6129,19 +6142,25 @@ static void igb_vmm_control(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; u32 reg; - /* replication is not supported for 82575 */ - if (hw->mac.type == e1000_82575) + switch (hw->mac.type) { + case e1000_82575: + default: + /* replication is not supported for 82575 */ return; - - /* enable replication vlan tag stripping */ - reg = rd32(E1000_RPLOLR); - reg |= E1000_RPLOLR_STRVLAN; - wr32(E1000_RPLOLR, reg); - - /* notify HW that the MAC is adding vlan tags */ - reg = rd32(E1000_DTXCTL); - reg |= E1000_DTXCTL_VLAN_ADDED; - wr32(E1000_DTXCTL, reg); + case e1000_82576: + /* notify HW that the MAC is adding vlan tags */ + reg = rd32(E1000_DTXCTL); + reg |= E1000_DTXCTL_VLAN_ADDED; + wr32(E1000_DTXCTL, reg); + case e1000_82580: + /* enable replication vlan tag stripping */ + reg = rd32(E1000_RPLOLR); + reg |= E1000_RPLOLR_STRVLAN; + wr32(E1000_RPLOLR, reg); + case e1000_i350: + /* none of the above registers are supported by i350 */ + break; + } if (adapter->vfs_allocated_count) { igb_vmdq_set_loopback_pf(hw, true); |