diff options
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/ethernet/intel/e100.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000_main.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ethtool.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 5 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc.h | 68 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_base.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_defines.h | 17 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_ethtool.c | 839 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_main.c | 447 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_regs.h | 16 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 |
12 files changed, 1392 insertions, 18 deletions
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 0fd268070fb4..a65d5a9ba7db 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c | |||
| @@ -2797,7 +2797,7 @@ static int e100_set_features(struct net_device *netdev, | |||
| 2797 | 2797 | ||
| 2798 | netdev->features = features; | 2798 | netdev->features = features; |
| 2799 | e100_exec_cb(nic, NULL, e100_configure); | 2799 | e100_exec_cb(nic, NULL, e100_configure); |
| 2800 | return 0; | 2800 | return 1; |
| 2801 | } | 2801 | } |
| 2802 | 2802 | ||
| 2803 | static const struct net_device_ops e100_netdev_ops = { | 2803 | static const struct net_device_ops e100_netdev_ops = { |
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 8fe9af0e2ab7..a7c76732849f 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | |||
| @@ -820,7 +820,7 @@ static int e1000_set_features(struct net_device *netdev, | |||
| 820 | else | 820 | else |
| 821 | e1000_reset(adapter); | 821 | e1000_reset(adapter); |
| 822 | 822 | ||
| 823 | return 0; | 823 | return 1; |
| 824 | } | 824 | } |
| 825 | 825 | ||
| 826 | static const struct net_device_ops e1000_netdev_ops = { | 826 | static const struct net_device_ops e1000_netdev_ops = { |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 7acc61e4f645..745c1242a2d9 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
| @@ -7003,7 +7003,7 @@ static int e1000_set_features(struct net_device *netdev, | |||
| 7003 | else | 7003 | else |
| 7004 | e1000e_reset(adapter); | 7004 | e1000e_reset(adapter); |
| 7005 | 7005 | ||
| 7006 | return 0; | 7006 | return 1; |
| 7007 | } | 7007 | } |
| 7008 | 7008 | ||
| 7009 | static const struct net_device_ops e1000e_netdev_ops = { | 7009 | static const struct net_device_ops e1000e_netdev_ops = { |
| @@ -7350,7 +7350,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 7350 | 7350 | ||
| 7351 | dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP); | 7351 | dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP); |
| 7352 | 7352 | ||
| 7353 | if (pci_dev_run_wake(pdev)) | 7353 | if (pci_dev_run_wake(pdev) && hw->mac.type < e1000_pch_cnp) |
| 7354 | pm_runtime_put_noidle(&pdev->dev); | 7354 | pm_runtime_put_noidle(&pdev->dev); |
| 7355 | 7355 | ||
| 7356 | return 0; | 7356 | return 0; |
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index c57671068245..c645d9e648e0 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c | |||
| @@ -3158,8 +3158,8 @@ static int igb_set_eee(struct net_device *netdev, | |||
| 3158 | } else if (!edata->eee_enabled) { | 3158 | } else if (!edata->eee_enabled) { |
| 3159 | dev_err(&adapter->pdev->dev, | 3159 | dev_err(&adapter->pdev->dev, |
| 3160 | "Setting EEE options are not supported with EEE disabled\n"); | 3160 | "Setting EEE options are not supported with EEE disabled\n"); |
| 3161 | return -EINVAL; | 3161 | return -EINVAL; |
| 3162 | } | 3162 | } |
| 3163 | 3163 | ||
| 3164 | adapter->eee_advert = ethtool_adv_to_mmd_eee_adv_t(edata->advertised); | 3164 | adapter->eee_advert = ethtool_adv_to_mmd_eee_adv_t(edata->advertised); |
| 3165 | if (hw->dev_spec._82575.eee_disable != !edata->eee_enabled) { | 3165 | if (hw->dev_spec._82575.eee_disable != !edata->eee_enabled) { |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 69b230c53fed..bea7175d171b 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
| @@ -2480,7 +2480,7 @@ static int igb_set_features(struct net_device *netdev, | |||
| 2480 | else | 2480 | else |
| 2481 | igb_reset(adapter); | 2481 | igb_reset(adapter); |
| 2482 | 2482 | ||
| 2483 | return 0; | 2483 | return 1; |
| 2484 | } | 2484 | } |
| 2485 | 2485 | ||
| 2486 | static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | 2486 | static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], |
| @@ -3452,6 +3452,9 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 3452 | break; | 3452 | break; |
| 3453 | } | 3453 | } |
| 3454 | } | 3454 | } |
| 3455 | |||
| 3456 | dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP); | ||
| 3457 | |||
| 3455 | pm_runtime_put_noidle(&pdev->dev); | 3458 | pm_runtime_put_noidle(&pdev->dev); |
| 3456 | return 0; | 3459 | return 0; |
| 3457 | 3460 | ||
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index 80faccc34cda..0f5534ce27b0 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h | |||
| @@ -29,9 +29,15 @@ unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter); | |||
| 29 | void igc_set_flag_queue_pairs(struct igc_adapter *adapter, | 29 | void igc_set_flag_queue_pairs(struct igc_adapter *adapter, |
| 30 | const u32 max_rss_queues); | 30 | const u32 max_rss_queues); |
| 31 | int igc_reinit_queues(struct igc_adapter *adapter); | 31 | int igc_reinit_queues(struct igc_adapter *adapter); |
| 32 | void igc_write_rss_indir_tbl(struct igc_adapter *adapter); | ||
| 32 | bool igc_has_link(struct igc_adapter *adapter); | 33 | bool igc_has_link(struct igc_adapter *adapter); |
| 33 | void igc_reset(struct igc_adapter *adapter); | 34 | void igc_reset(struct igc_adapter *adapter); |
| 34 | int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx); | 35 | int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx); |
| 36 | int igc_add_mac_steering_filter(struct igc_adapter *adapter, | ||
| 37 | const u8 *addr, u8 queue, u8 flags); | ||
| 38 | int igc_del_mac_steering_filter(struct igc_adapter *adapter, | ||
| 39 | const u8 *addr, u8 queue, u8 flags); | ||
| 40 | void igc_update_stats(struct igc_adapter *adapter); | ||
| 35 | 41 | ||
| 36 | extern char igc_driver_name[]; | 42 | extern char igc_driver_name[]; |
| 37 | extern char igc_driver_version[]; | 43 | extern char igc_driver_version[]; |
| @@ -51,6 +57,13 @@ extern char igc_driver_version[]; | |||
| 51 | #define IGC_FLAG_VLAN_PROMISC BIT(15) | 57 | #define IGC_FLAG_VLAN_PROMISC BIT(15) |
| 52 | #define IGC_FLAG_RX_LEGACY BIT(16) | 58 | #define IGC_FLAG_RX_LEGACY BIT(16) |
| 53 | 59 | ||
| 60 | #define IGC_FLAG_RSS_FIELD_IPV4_UDP BIT(6) | ||
| 61 | #define IGC_FLAG_RSS_FIELD_IPV6_UDP BIT(7) | ||
| 62 | |||
| 63 | #define IGC_MRQC_ENABLE_RSS_MQ 0x00000002 | ||
| 64 | #define IGC_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 | ||
| 65 | #define IGC_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 | ||
| 66 | |||
| 54 | #define IGC_START_ITR 648 /* ~6000 ints/sec */ | 67 | #define IGC_START_ITR 648 /* ~6000 ints/sec */ |
| 55 | #define IGC_4K_ITR 980 | 68 | #define IGC_4K_ITR 980 |
| 56 | #define IGC_20K_ITR 196 | 69 | #define IGC_20K_ITR 196 |
| @@ -284,15 +297,50 @@ struct igc_q_vector { | |||
| 284 | struct igc_ring ring[0] ____cacheline_internodealigned_in_smp; | 297 | struct igc_ring ring[0] ____cacheline_internodealigned_in_smp; |
| 285 | }; | 298 | }; |
| 286 | 299 | ||
| 300 | #define MAX_ETYPE_FILTER (4 - 1) | ||
| 301 | |||
| 302 | enum igc_filter_match_flags { | ||
| 303 | IGC_FILTER_FLAG_ETHER_TYPE = 0x1, | ||
| 304 | IGC_FILTER_FLAG_VLAN_TCI = 0x2, | ||
| 305 | IGC_FILTER_FLAG_SRC_MAC_ADDR = 0x4, | ||
| 306 | IGC_FILTER_FLAG_DST_MAC_ADDR = 0x8, | ||
| 307 | }; | ||
| 308 | |||
| 309 | /* RX network flow classification data structure */ | ||
| 310 | struct igc_nfc_input { | ||
| 311 | /* Byte layout in order, all values with MSB first: | ||
| 312 | * match_flags - 1 byte | ||
| 313 | * etype - 2 bytes | ||
| 314 | * vlan_tci - 2 bytes | ||
| 315 | */ | ||
| 316 | u8 match_flags; | ||
| 317 | __be16 etype; | ||
| 318 | __be16 vlan_tci; | ||
| 319 | u8 src_addr[ETH_ALEN]; | ||
| 320 | u8 dst_addr[ETH_ALEN]; | ||
| 321 | }; | ||
| 322 | |||
| 323 | struct igc_nfc_filter { | ||
| 324 | struct hlist_node nfc_node; | ||
| 325 | struct igc_nfc_input filter; | ||
| 326 | unsigned long cookie; | ||
| 327 | u16 etype_reg_index; | ||
| 328 | u16 sw_idx; | ||
| 329 | u16 action; | ||
| 330 | }; | ||
| 331 | |||
| 287 | struct igc_mac_addr { | 332 | struct igc_mac_addr { |
| 288 | u8 addr[ETH_ALEN]; | 333 | u8 addr[ETH_ALEN]; |
| 289 | u8 queue; | 334 | u8 queue; |
| 290 | u8 state; /* bitmask */ | 335 | u8 state; /* bitmask */ |
| 291 | }; | 336 | }; |
| 292 | 337 | ||
| 293 | #define IGC_MAC_STATE_DEFAULT 0x1 | 338 | #define IGC_MAC_STATE_DEFAULT 0x1 |
| 294 | #define IGC_MAC_STATE_MODIFIED 0x2 | 339 | #define IGC_MAC_STATE_IN_USE 0x2 |
| 295 | #define IGC_MAC_STATE_IN_USE 0x4 | 340 | #define IGC_MAC_STATE_SRC_ADDR 0x4 |
| 341 | #define IGC_MAC_STATE_QUEUE_STEERING 0x8 | ||
| 342 | |||
| 343 | #define IGC_MAX_RXNFC_FILTERS 16 | ||
| 296 | 344 | ||
| 297 | /* Board specific private data structure */ | 345 | /* Board specific private data structure */ |
| 298 | struct igc_adapter { | 346 | struct igc_adapter { |
| @@ -356,12 +404,22 @@ struct igc_adapter { | |||
| 356 | u16 tx_ring_count; | 404 | u16 tx_ring_count; |
| 357 | u16 rx_ring_count; | 405 | u16 rx_ring_count; |
| 358 | 406 | ||
| 407 | u32 tx_hwtstamp_timeouts; | ||
| 408 | u32 tx_hwtstamp_skipped; | ||
| 409 | u32 rx_hwtstamp_cleared; | ||
| 359 | u32 *shadow_vfta; | 410 | u32 *shadow_vfta; |
| 360 | 411 | ||
| 361 | u32 rss_queues; | 412 | u32 rss_queues; |
| 413 | u32 rss_indir_tbl_init; | ||
| 414 | |||
| 415 | /* RX network flow classification support */ | ||
| 416 | struct hlist_head nfc_filter_list; | ||
| 417 | struct hlist_head cls_flower_list; | ||
| 418 | unsigned int nfc_filter_count; | ||
| 362 | 419 | ||
| 363 | /* lock for RX network flow classification filter */ | 420 | /* lock for RX network flow classification filter */ |
| 364 | spinlock_t nfc_lock; | 421 | spinlock_t nfc_lock; |
| 422 | bool etype_bitmap[MAX_ETYPE_FILTER]; | ||
| 365 | 423 | ||
| 366 | struct igc_mac_addr *mac_table; | 424 | struct igc_mac_addr *mac_table; |
| 367 | 425 | ||
| @@ -447,6 +505,10 @@ static inline s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data) | |||
| 447 | 505 | ||
| 448 | /* forward declaration */ | 506 | /* forward declaration */ |
| 449 | void igc_reinit_locked(struct igc_adapter *); | 507 | void igc_reinit_locked(struct igc_adapter *); |
| 508 | int igc_add_filter(struct igc_adapter *adapter, | ||
| 509 | struct igc_nfc_filter *input); | ||
| 510 | int igc_erase_filter(struct igc_adapter *adapter, | ||
| 511 | struct igc_nfc_filter *input); | ||
| 450 | 512 | ||
| 451 | #define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring)) | 513 | #define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring)) |
| 452 | 514 | ||
diff --git a/drivers/net/ethernet/intel/igc/igc_base.h b/drivers/net/ethernet/intel/igc/igc_base.h index 76d4991d7284..58d1109d7f3f 100644 --- a/drivers/net/ethernet/intel/igc/igc_base.h +++ b/drivers/net/ethernet/intel/igc/igc_base.h | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* Copyright (c) 2018 Intel Corporation */ | 2 | /* Copyright (c) 2018 Intel Corporation */ |
| 3 | 3 | ||
| 4 | #ifndef _IGC_BASE_H | 4 | #ifndef _IGC_BASE_H_ |
| 5 | #define _IGC_BASE_H | 5 | #define _IGC_BASE_H_ |
| 6 | 6 | ||
| 7 | /* forward declaration */ | 7 | /* forward declaration */ |
| 8 | void igc_rx_fifo_flush_base(struct igc_hw *hw); | 8 | void igc_rx_fifo_flush_base(struct igc_hw *hw); |
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h index 7d1bdcd1225a..a9a30268de59 100644 --- a/drivers/net/ethernet/intel/igc/igc_defines.h +++ b/drivers/net/ethernet/intel/igc/igc_defines.h | |||
| @@ -310,6 +310,12 @@ | |||
| 310 | IGC_RXDEXT_STATERR_CXE | \ | 310 | IGC_RXDEXT_STATERR_CXE | \ |
| 311 | IGC_RXDEXT_STATERR_RXE) | 311 | IGC_RXDEXT_STATERR_RXE) |
| 312 | 312 | ||
| 313 | #define IGC_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 | ||
| 314 | #define IGC_MRQC_RSS_FIELD_IPV4 0x00020000 | ||
| 315 | #define IGC_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000 | ||
| 316 | #define IGC_MRQC_RSS_FIELD_IPV6 0x00100000 | ||
| 317 | #define IGC_MRQC_RSS_FIELD_IPV6_TCP 0x00200000 | ||
| 318 | |||
| 313 | /* Header split receive */ | 319 | /* Header split receive */ |
| 314 | #define IGC_RFCTL_IPV6_EX_DIS 0x00010000 | 320 | #define IGC_RFCTL_IPV6_EX_DIS 0x00010000 |
| 315 | #define IGC_RFCTL_LEF 0x00040000 | 321 | #define IGC_RFCTL_LEF 0x00040000 |
| @@ -325,6 +331,10 @@ | |||
| 325 | #define I225_RXPBSIZE_DEFAULT 0x000000A2 /* RXPBSIZE default */ | 331 | #define I225_RXPBSIZE_DEFAULT 0x000000A2 /* RXPBSIZE default */ |
| 326 | #define I225_TXPBSIZE_DEFAULT 0x04000014 /* TXPBSIZE default */ | 332 | #define I225_TXPBSIZE_DEFAULT 0x04000014 /* TXPBSIZE default */ |
| 327 | 333 | ||
| 334 | /* Receive Checksum Control */ | ||
| 335 | #define IGC_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */ | ||
| 336 | #define IGC_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ | ||
| 337 | |||
| 328 | /* GPY211 - I225 defines */ | 338 | /* GPY211 - I225 defines */ |
| 329 | #define GPY_MMD_MASK 0xFFFF0000 | 339 | #define GPY_MMD_MASK 0xFFFF0000 |
| 330 | #define GPY_MMD_SHIFT 16 | 340 | #define GPY_MMD_SHIFT 16 |
| @@ -390,4 +400,11 @@ | |||
| 390 | 400 | ||
| 391 | #define IGC_N0_QUEUE -1 | 401 | #define IGC_N0_QUEUE -1 |
| 392 | 402 | ||
| 403 | #define IGC_MAX_MAC_HDR_LEN 127 | ||
| 404 | #define IGC_MAX_NETWORK_HDR_LEN 511 | ||
| 405 | |||
| 406 | #define IGC_VLAPQF_QUEUE_SEL(_n, q_idx) ((q_idx) << ((_n) * 4)) | ||
| 407 | #define IGC_VLAPQF_P_VALID(_n) (0x1 << (3 + (_n) * 4)) | ||
| 408 | #define IGC_VLAPQF_QUEUE_MASK 0x03 | ||
| 409 | |||
| 393 | #endif /* _IGC_DEFINES_H_ */ | 410 | #endif /* _IGC_DEFINES_H_ */ |
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index eff37a6c0afa..ac98f1d96892 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c | |||
| @@ -2,10 +2,120 @@ | |||
| 2 | /* Copyright (c) 2018 Intel Corporation */ | 2 | /* Copyright (c) 2018 Intel Corporation */ |
| 3 | 3 | ||
| 4 | /* ethtool support for igc */ | 4 | /* ethtool support for igc */ |
| 5 | #include <linux/if_vlan.h> | ||
| 5 | #include <linux/pm_runtime.h> | 6 | #include <linux/pm_runtime.h> |
| 6 | 7 | ||
| 7 | #include "igc.h" | 8 | #include "igc.h" |
| 8 | 9 | ||
| 10 | /* forward declaration */ | ||
| 11 | struct igc_stats { | ||
| 12 | char stat_string[ETH_GSTRING_LEN]; | ||
| 13 | int sizeof_stat; | ||
| 14 | int stat_offset; | ||
| 15 | }; | ||
| 16 | |||
| 17 | #define IGC_STAT(_name, _stat) { \ | ||
| 18 | .stat_string = _name, \ | ||
| 19 | .sizeof_stat = FIELD_SIZEOF(struct igc_adapter, _stat), \ | ||
| 20 | .stat_offset = offsetof(struct igc_adapter, _stat) \ | ||
| 21 | } | ||
| 22 | |||
| 23 | static const struct igc_stats igc_gstrings_stats[] = { | ||
| 24 | IGC_STAT("rx_packets", stats.gprc), | ||
| 25 | IGC_STAT("tx_packets", stats.gptc), | ||
| 26 | IGC_STAT("rx_bytes", stats.gorc), | ||
| 27 | IGC_STAT("tx_bytes", stats.gotc), | ||
| 28 | IGC_STAT("rx_broadcast", stats.bprc), | ||
| 29 | IGC_STAT("tx_broadcast", stats.bptc), | ||
| 30 | IGC_STAT("rx_multicast", stats.mprc), | ||
| 31 | IGC_STAT("tx_multicast", stats.mptc), | ||
| 32 | IGC_STAT("multicast", stats.mprc), | ||
| 33 | IGC_STAT("collisions", stats.colc), | ||
| 34 | IGC_STAT("rx_crc_errors", stats.crcerrs), | ||
| 35 | IGC_STAT("rx_no_buffer_count", stats.rnbc), | ||
| 36 | IGC_STAT("rx_missed_errors", stats.mpc), | ||
| 37 | IGC_STAT("tx_aborted_errors", stats.ecol), | ||
| 38 | IGC_STAT("tx_carrier_errors", stats.tncrs), | ||
| 39 | IGC_STAT("tx_window_errors", stats.latecol), | ||
| 40 | IGC_STAT("tx_abort_late_coll", stats.latecol), | ||
| 41 | IGC_STAT("tx_deferred_ok", stats.dc), | ||
| 42 | IGC_STAT("tx_single_coll_ok", stats.scc), | ||
| 43 | IGC_STAT("tx_multi_coll_ok", stats.mcc), | ||
| 44 | IGC_STAT("tx_timeout_count", tx_timeout_count), | ||
| 45 | IGC_STAT("rx_long_length_errors", stats.roc), | ||
| 46 | IGC_STAT("rx_short_length_errors", stats.ruc), | ||
| 47 | IGC_STAT("rx_align_errors", stats.algnerrc), | ||
| 48 | IGC_STAT("tx_tcp_seg_good", stats.tsctc), | ||
| 49 | IGC_STAT("tx_tcp_seg_failed", stats.tsctfc), | ||
| 50 | IGC_STAT("rx_flow_control_xon", stats.xonrxc), | ||
| 51 | IGC_STAT("rx_flow_control_xoff", stats.xoffrxc), | ||
| 52 | IGC_STAT("tx_flow_control_xon", stats.xontxc), | ||
| 53 | IGC_STAT("tx_flow_control_xoff", stats.xofftxc), | ||
| 54 | IGC_STAT("rx_long_byte_count", stats.gorc), | ||
| 55 | IGC_STAT("tx_dma_out_of_sync", stats.doosync), | ||
| 56 | IGC_STAT("tx_smbus", stats.mgptc), | ||
| 57 | IGC_STAT("rx_smbus", stats.mgprc), | ||
| 58 | IGC_STAT("dropped_smbus", stats.mgpdc), | ||
| 59 | IGC_STAT("os2bmc_rx_by_bmc", stats.o2bgptc), | ||
| 60 | IGC_STAT("os2bmc_tx_by_bmc", stats.b2ospc), | ||
| 61 | IGC_STAT("os2bmc_tx_by_host", stats.o2bspc), | ||
| 62 | IGC_STAT("os2bmc_rx_by_host", stats.b2ogprc), | ||
| 63 | IGC_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts), | ||
| 64 | IGC_STAT("tx_hwtstamp_skipped", tx_hwtstamp_skipped), | ||
| 65 | IGC_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), | ||
| 66 | }; | ||
| 67 | |||
| 68 | #define IGC_NETDEV_STAT(_net_stat) { \ | ||
| 69 | .stat_string = __stringify(_net_stat), \ | ||
| 70 | .sizeof_stat = FIELD_SIZEOF(struct rtnl_link_stats64, _net_stat), \ | ||
| 71 | .stat_offset = offsetof(struct rtnl_link_stats64, _net_stat) \ | ||
| 72 | } | ||
| 73 | |||
| 74 | static const struct igc_stats igc_gstrings_net_stats[] = { | ||
| 75 | IGC_NETDEV_STAT(rx_errors), | ||
| 76 | IGC_NETDEV_STAT(tx_errors), | ||
| 77 | IGC_NETDEV_STAT(tx_dropped), | ||
| 78 | IGC_NETDEV_STAT(rx_length_errors), | ||
| 79 | IGC_NETDEV_STAT(rx_over_errors), | ||
| 80 | IGC_NETDEV_STAT(rx_frame_errors), | ||
| 81 | IGC_NETDEV_STAT(rx_fifo_errors), | ||
| 82 | IGC_NETDEV_STAT(tx_fifo_errors), | ||
| 83 | IGC_NETDEV_STAT(tx_heartbeat_errors) | ||
| 84 | }; | ||
| 85 | |||
| 86 | enum igc_diagnostics_results { | ||
| 87 | TEST_REG = 0, | ||
| 88 | TEST_EEP, | ||
| 89 | TEST_IRQ, | ||
| 90 | TEST_LOOP, | ||
| 91 | TEST_LINK | ||
| 92 | }; | ||
| 93 | |||
| 94 | static const char igc_gstrings_test[][ETH_GSTRING_LEN] = { | ||
| 95 | [TEST_REG] = "Register test (offline)", | ||
| 96 | [TEST_EEP] = "Eeprom test (offline)", | ||
| 97 | [TEST_IRQ] = "Interrupt test (offline)", | ||
| 98 | [TEST_LOOP] = "Loopback test (offline)", | ||
| 99 | [TEST_LINK] = "Link test (on/offline)" | ||
| 100 | }; | ||
| 101 | |||
| 102 | #define IGC_TEST_LEN (sizeof(igc_gstrings_test) / ETH_GSTRING_LEN) | ||
| 103 | |||
| 104 | #define IGC_GLOBAL_STATS_LEN \ | ||
| 105 | (sizeof(igc_gstrings_stats) / sizeof(struct igc_stats)) | ||
| 106 | #define IGC_NETDEV_STATS_LEN \ | ||
| 107 | (sizeof(igc_gstrings_net_stats) / sizeof(struct igc_stats)) | ||
| 108 | #define IGC_RX_QUEUE_STATS_LEN \ | ||
| 109 | (sizeof(struct igc_rx_queue_stats) / sizeof(u64)) | ||
| 110 | #define IGC_TX_QUEUE_STATS_LEN 3 /* packets, bytes, restart_queue */ | ||
| 111 | #define IGC_QUEUE_STATS_LEN \ | ||
| 112 | ((((struct igc_adapter *)netdev_priv(netdev))->num_rx_queues * \ | ||
| 113 | IGC_RX_QUEUE_STATS_LEN) + \ | ||
| 114 | (((struct igc_adapter *)netdev_priv(netdev))->num_tx_queues * \ | ||
| 115 | IGC_TX_QUEUE_STATS_LEN)) | ||
| 116 | #define IGC_STATS_LEN \ | ||
| 117 | (IGC_GLOBAL_STATS_LEN + IGC_NETDEV_STATS_LEN + IGC_QUEUE_STATS_LEN) | ||
| 118 | |||
| 9 | static const char igc_priv_flags_strings[][ETH_GSTRING_LEN] = { | 119 | static const char igc_priv_flags_strings[][ETH_GSTRING_LEN] = { |
| 10 | #define IGC_PRIV_FLAGS_LEGACY_RX BIT(0) | 120 | #define IGC_PRIV_FLAGS_LEGACY_RX BIT(0) |
| 11 | "legacy-rx", | 121 | "legacy-rx", |
| @@ -545,6 +655,127 @@ static int igc_set_pauseparam(struct net_device *netdev, | |||
| 545 | return retval; | 655 | return retval; |
| 546 | } | 656 | } |
| 547 | 657 | ||
| 658 | static void igc_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | ||
| 659 | { | ||
| 660 | struct igc_adapter *adapter = netdev_priv(netdev); | ||
| 661 | u8 *p = data; | ||
| 662 | int i; | ||
| 663 | |||
| 664 | switch (stringset) { | ||
| 665 | case ETH_SS_TEST: | ||
| 666 | memcpy(data, *igc_gstrings_test, | ||
| 667 | IGC_TEST_LEN * ETH_GSTRING_LEN); | ||
| 668 | break; | ||
| 669 | case ETH_SS_STATS: | ||
| 670 | for (i = 0; i < IGC_GLOBAL_STATS_LEN; i++) { | ||
| 671 | memcpy(p, igc_gstrings_stats[i].stat_string, | ||
| 672 | ETH_GSTRING_LEN); | ||
| 673 | p += ETH_GSTRING_LEN; | ||
| 674 | } | ||
| 675 | for (i = 0; i < IGC_NETDEV_STATS_LEN; i++) { | ||
| 676 | memcpy(p, igc_gstrings_net_stats[i].stat_string, | ||
| 677 | ETH_GSTRING_LEN); | ||
| 678 | p += ETH_GSTRING_LEN; | ||
| 679 | } | ||
| 680 | for (i = 0; i < adapter->num_tx_queues; i++) { | ||
| 681 | sprintf(p, "tx_queue_%u_packets", i); | ||
| 682 | p += ETH_GSTRING_LEN; | ||
| 683 | sprintf(p, "tx_queue_%u_bytes", i); | ||
| 684 | p += ETH_GSTRING_LEN; | ||
| 685 | sprintf(p, "tx_queue_%u_restart", i); | ||
| 686 | p += ETH_GSTRING_LEN; | ||
| 687 | } | ||
| 688 | for (i = 0; i < adapter->num_rx_queues; i++) { | ||
| 689 | sprintf(p, "rx_queue_%u_packets", i); | ||
| 690 | p += ETH_GSTRING_LEN; | ||
| 691 | sprintf(p, "rx_queue_%u_bytes", i); | ||
| 692 | p += ETH_GSTRING_LEN; | ||
| 693 | sprintf(p, "rx_queue_%u_drops", i); | ||
| 694 | p += ETH_GSTRING_LEN; | ||
| 695 | sprintf(p, "rx_queue_%u_csum_err", i); | ||
| 696 | p += ETH_GSTRING_LEN; | ||
| 697 | sprintf(p, "rx_queue_%u_alloc_failed", i); | ||
| 698 | p += ETH_GSTRING_LEN; | ||
| 699 | } | ||
| 700 | /* BUG_ON(p - data != IGC_STATS_LEN * ETH_GSTRING_LEN); */ | ||
| 701 | break; | ||
| 702 | case ETH_SS_PRIV_FLAGS: | ||
| 703 | memcpy(data, igc_priv_flags_strings, | ||
| 704 | IGC_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN); | ||
| 705 | break; | ||
| 706 | } | ||
| 707 | } | ||
| 708 | |||
| 709 | static int igc_get_sset_count(struct net_device *netdev, int sset) | ||
| 710 | { | ||
| 711 | switch (sset) { | ||
| 712 | case ETH_SS_STATS: | ||
| 713 | return IGC_STATS_LEN; | ||
| 714 | case ETH_SS_TEST: | ||
| 715 | return IGC_TEST_LEN; | ||
| 716 | case ETH_SS_PRIV_FLAGS: | ||
| 717 | return IGC_PRIV_FLAGS_STR_LEN; | ||
| 718 | default: | ||
| 719 | return -ENOTSUPP; | ||
| 720 | } | ||
| 721 | } | ||
| 722 | |||
| 723 | static void igc_get_ethtool_stats(struct net_device *netdev, | ||
| 724 | struct ethtool_stats *stats, u64 *data) | ||
| 725 | { | ||
| 726 | struct igc_adapter *adapter = netdev_priv(netdev); | ||
| 727 | struct rtnl_link_stats64 *net_stats = &adapter->stats64; | ||
| 728 | unsigned int start; | ||
| 729 | struct igc_ring *ring; | ||
| 730 | int i, j; | ||
| 731 | char *p; | ||
| 732 | |||
| 733 | spin_lock(&adapter->stats64_lock); | ||
| 734 | igc_update_stats(adapter); | ||
| 735 | |||
| 736 | for (i = 0; i < IGC_GLOBAL_STATS_LEN; i++) { | ||
| 737 | p = (char *)adapter + igc_gstrings_stats[i].stat_offset; | ||
| 738 | data[i] = (igc_gstrings_stats[i].sizeof_stat == | ||
| 739 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; | ||
| 740 | } | ||
| 741 | for (j = 0; j < IGC_NETDEV_STATS_LEN; j++, i++) { | ||
| 742 | p = (char *)net_stats + igc_gstrings_net_stats[j].stat_offset; | ||
| 743 | data[i] = (igc_gstrings_net_stats[j].sizeof_stat == | ||
| 744 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; | ||
| 745 | } | ||
| 746 | for (j = 0; j < adapter->num_tx_queues; j++) { | ||
| 747 | u64 restart2; | ||
| 748 | |||
| 749 | ring = adapter->tx_ring[j]; | ||
| 750 | do { | ||
| 751 | start = u64_stats_fetch_begin_irq(&ring->tx_syncp); | ||
| 752 | data[i] = ring->tx_stats.packets; | ||
| 753 | data[i + 1] = ring->tx_stats.bytes; | ||
| 754 | data[i + 2] = ring->tx_stats.restart_queue; | ||
| 755 | } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); | ||
| 756 | do { | ||
| 757 | start = u64_stats_fetch_begin_irq(&ring->tx_syncp2); | ||
| 758 | restart2 = ring->tx_stats.restart_queue2; | ||
| 759 | } while (u64_stats_fetch_retry_irq(&ring->tx_syncp2, start)); | ||
| 760 | data[i + 2] += restart2; | ||
| 761 | |||
| 762 | i += IGC_TX_QUEUE_STATS_LEN; | ||
| 763 | } | ||
| 764 | for (j = 0; j < adapter->num_rx_queues; j++) { | ||
| 765 | ring = adapter->rx_ring[j]; | ||
| 766 | do { | ||
| 767 | start = u64_stats_fetch_begin_irq(&ring->rx_syncp); | ||
| 768 | data[i] = ring->rx_stats.packets; | ||
| 769 | data[i + 1] = ring->rx_stats.bytes; | ||
| 770 | data[i + 2] = ring->rx_stats.drops; | ||
| 771 | data[i + 3] = ring->rx_stats.csum_err; | ||
| 772 | data[i + 4] = ring->rx_stats.alloc_failed; | ||
| 773 | } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); | ||
| 774 | i += IGC_RX_QUEUE_STATS_LEN; | ||
| 775 | } | ||
| 776 | spin_unlock(&adapter->stats64_lock); | ||
| 777 | } | ||
| 778 | |||
| 548 | static int igc_get_coalesce(struct net_device *netdev, | 779 | static int igc_get_coalesce(struct net_device *netdev, |
| 549 | struct ethtool_coalesce *ec) | 780 | struct ethtool_coalesce *ec) |
| 550 | { | 781 | { |
| @@ -643,6 +874,605 @@ static int igc_set_coalesce(struct net_device *netdev, | |||
| 643 | return 0; | 874 | return 0; |
| 644 | } | 875 | } |
| 645 | 876 | ||
| 877 | #define ETHER_TYPE_FULL_MASK ((__force __be16)~0) | ||
| 878 | static int igc_get_ethtool_nfc_entry(struct igc_adapter *adapter, | ||
| 879 | struct ethtool_rxnfc *cmd) | ||
| 880 | { | ||
| 881 | struct ethtool_rx_flow_spec *fsp = &cmd->fs; | ||
| 882 | struct igc_nfc_filter *rule = NULL; | ||
| 883 | |||
| 884 | /* report total rule count */ | ||
| 885 | cmd->data = IGC_MAX_RXNFC_FILTERS; | ||
| 886 | |||
| 887 | hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) { | ||
| 888 | if (fsp->location <= rule->sw_idx) | ||
| 889 | break; | ||
| 890 | } | ||
| 891 | |||
| 892 | if (!rule || fsp->location != rule->sw_idx) | ||
| 893 | return -EINVAL; | ||
| 894 | |||
| 895 | if (rule->filter.match_flags) { | ||
| 896 | fsp->flow_type = ETHER_FLOW; | ||
| 897 | fsp->ring_cookie = rule->action; | ||
| 898 | if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) { | ||
| 899 | fsp->h_u.ether_spec.h_proto = rule->filter.etype; | ||
| 900 | fsp->m_u.ether_spec.h_proto = ETHER_TYPE_FULL_MASK; | ||
| 901 | } | ||
| 902 | if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) { | ||
| 903 | fsp->flow_type |= FLOW_EXT; | ||
| 904 | fsp->h_ext.vlan_tci = rule->filter.vlan_tci; | ||
| 905 | fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK); | ||
| 906 | } | ||
| 907 | if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) { | ||
| 908 | ether_addr_copy(fsp->h_u.ether_spec.h_dest, | ||
| 909 | rule->filter.dst_addr); | ||
| 910 | /* As we only support matching by the full | ||
| 911 | * mask, return the mask to userspace | ||
| 912 | */ | ||
| 913 | eth_broadcast_addr(fsp->m_u.ether_spec.h_dest); | ||
| 914 | } | ||
| 915 | if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) { | ||
| 916 | ether_addr_copy(fsp->h_u.ether_spec.h_source, | ||
| 917 | rule->filter.src_addr); | ||
| 918 | /* As we only support matching by the full | ||
| 919 | * mask, return the mask to userspace | ||
| 920 | */ | ||
| 921 | eth_broadcast_addr(fsp->m_u.ether_spec.h_source); | ||
| 922 | } | ||
| 923 | |||
| 924 | return 0; | ||
| 925 | } | ||
| 926 | return -EINVAL; | ||
| 927 | } | ||
| 928 | |||
| 929 | static int igc_get_ethtool_nfc_all(struct igc_adapter *adapter, | ||
| 930 | struct ethtool_rxnfc *cmd, | ||
| 931 | u32 *rule_locs) | ||
| 932 | { | ||
| 933 | struct igc_nfc_filter *rule; | ||
| 934 | int cnt = 0; | ||
| 935 | |||
| 936 | /* report total rule count */ | ||
| 937 | cmd->data = IGC_MAX_RXNFC_FILTERS; | ||
| 938 | |||
| 939 | hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) { | ||
| 940 | if (cnt == cmd->rule_cnt) | ||
| 941 | return -EMSGSIZE; | ||
| 942 | rule_locs[cnt] = rule->sw_idx; | ||
| 943 | cnt++; | ||
| 944 | } | ||
| 945 | |||
| 946 | cmd->rule_cnt = cnt; | ||
| 947 | |||
| 948 | return 0; | ||
| 949 | } | ||
| 950 | |||
| 951 | static int igc_get_rss_hash_opts(struct igc_adapter *adapter, | ||
| 952 | struct ethtool_rxnfc *cmd) | ||
| 953 | { | ||
| 954 | cmd->data = 0; | ||
| 955 | |||
| 956 | /* Report default options for RSS on igc */ | ||
| 957 | switch (cmd->flow_type) { | ||
| 958 | case TCP_V4_FLOW: | ||
| 959 | cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
| 960 | /* Fall through */ | ||
| 961 | case UDP_V4_FLOW: | ||
| 962 | if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV4_UDP) | ||
| 963 | cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
| 964 | /* Fall through */ | ||
| 965 | case SCTP_V4_FLOW: | ||
| 966 | /* Fall through */ | ||
| 967 | case AH_ESP_V4_FLOW: | ||
| 968 | /* Fall through */ | ||
| 969 | case AH_V4_FLOW: | ||
| 970 | /* Fall through */ | ||
| 971 | case ESP_V4_FLOW: | ||
| 972 | /* Fall through */ | ||
| 973 | case IPV4_FLOW: | ||
| 974 | cmd->data |= RXH_IP_SRC | RXH_IP_DST; | ||
| 975 | break; | ||
| 976 | case TCP_V6_FLOW: | ||
| 977 | cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
| 978 | /* Fall through */ | ||
| 979 | case UDP_V6_FLOW: | ||
| 980 | if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV6_UDP) | ||
| 981 | cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
| 982 | /* Fall through */ | ||
| 983 | case SCTP_V6_FLOW: | ||
| 984 | /* Fall through */ | ||
| 985 | case AH_ESP_V6_FLOW: | ||
| 986 | /* Fall through */ | ||
| 987 | case AH_V6_FLOW: | ||
| 988 | /* Fall through */ | ||
| 989 | case ESP_V6_FLOW: | ||
| 990 | /* Fall through */ | ||
| 991 | case IPV6_FLOW: | ||
| 992 | cmd->data |= RXH_IP_SRC | RXH_IP_DST; | ||
| 993 | break; | ||
| 994 | default: | ||
| 995 | return -EINVAL; | ||
| 996 | } | ||
| 997 | |||
| 998 | return 0; | ||
| 999 | } | ||
| 1000 | |||
| 1001 | static int igc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, | ||
| 1002 | u32 *rule_locs) | ||
| 1003 | { | ||
| 1004 | struct igc_adapter *adapter = netdev_priv(dev); | ||
| 1005 | int ret = -EOPNOTSUPP; | ||
| 1006 | |||
| 1007 | switch (cmd->cmd) { | ||
| 1008 | case ETHTOOL_GRXRINGS: | ||
| 1009 | cmd->data = adapter->num_rx_queues; | ||
| 1010 | ret = 0; | ||
| 1011 | break; | ||
| 1012 | case ETHTOOL_GRXCLSRLCNT: | ||
| 1013 | cmd->rule_cnt = adapter->nfc_filter_count; | ||
| 1014 | ret = 0; | ||
| 1015 | break; | ||
| 1016 | case ETHTOOL_GRXCLSRULE: | ||
| 1017 | ret = igc_get_ethtool_nfc_entry(adapter, cmd); | ||
| 1018 | break; | ||
| 1019 | case ETHTOOL_GRXCLSRLALL: | ||
| 1020 | ret = igc_get_ethtool_nfc_all(adapter, cmd, rule_locs); | ||
| 1021 | break; | ||
| 1022 | case ETHTOOL_GRXFH: | ||
| 1023 | ret = igc_get_rss_hash_opts(adapter, cmd); | ||
| 1024 | break; | ||
| 1025 | default: | ||
| 1026 | break; | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | return ret; | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | #define UDP_RSS_FLAGS (IGC_FLAG_RSS_FIELD_IPV4_UDP | \ | ||
| 1033 | IGC_FLAG_RSS_FIELD_IPV6_UDP) | ||
| 1034 | static int igc_set_rss_hash_opt(struct igc_adapter *adapter, | ||
| 1035 | struct ethtool_rxnfc *nfc) | ||
| 1036 | { | ||
| 1037 | u32 flags = adapter->flags; | ||
| 1038 | |||
| 1039 | /* RSS does not support anything other than hashing | ||
| 1040 | * to queues on src and dst IPs and ports | ||
| 1041 | */ | ||
| 1042 | if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST | | ||
| 1043 | RXH_L4_B_0_1 | RXH_L4_B_2_3)) | ||
| 1044 | return -EINVAL; | ||
| 1045 | |||
| 1046 | switch (nfc->flow_type) { | ||
| 1047 | case TCP_V4_FLOW: | ||
| 1048 | case TCP_V6_FLOW: | ||
| 1049 | if (!(nfc->data & RXH_IP_SRC) || | ||
| 1050 | !(nfc->data & RXH_IP_DST) || | ||
| 1051 | !(nfc->data & RXH_L4_B_0_1) || | ||
| 1052 | !(nfc->data & RXH_L4_B_2_3)) | ||
| 1053 | return -EINVAL; | ||
| 1054 | break; | ||
| 1055 | case UDP_V4_FLOW: | ||
| 1056 | if (!(nfc->data & RXH_IP_SRC) || | ||
| 1057 | !(nfc->data & RXH_IP_DST)) | ||
| 1058 | return -EINVAL; | ||
| 1059 | switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { | ||
| 1060 | case 0: | ||
| 1061 | flags &= ~IGC_FLAG_RSS_FIELD_IPV4_UDP; | ||
| 1062 | break; | ||
| 1063 | case (RXH_L4_B_0_1 | RXH_L4_B_2_3): | ||
| 1064 | flags |= IGC_FLAG_RSS_FIELD_IPV4_UDP; | ||
| 1065 | break; | ||
| 1066 | default: | ||
| 1067 | return -EINVAL; | ||
| 1068 | } | ||
| 1069 | break; | ||
| 1070 | case UDP_V6_FLOW: | ||
| 1071 | if (!(nfc->data & RXH_IP_SRC) || | ||
| 1072 | !(nfc->data & RXH_IP_DST)) | ||
| 1073 | return -EINVAL; | ||
| 1074 | switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { | ||
| 1075 | case 0: | ||
| 1076 | flags &= ~IGC_FLAG_RSS_FIELD_IPV6_UDP; | ||
| 1077 | break; | ||
| 1078 | case (RXH_L4_B_0_1 | RXH_L4_B_2_3): | ||
| 1079 | flags |= IGC_FLAG_RSS_FIELD_IPV6_UDP; | ||
| 1080 | break; | ||
| 1081 | default: | ||
| 1082 | return -EINVAL; | ||
| 1083 | } | ||
| 1084 | break; | ||
| 1085 | case AH_ESP_V4_FLOW: | ||
| 1086 | case AH_V4_FLOW: | ||
| 1087 | case ESP_V4_FLOW: | ||
| 1088 | case SCTP_V4_FLOW: | ||
| 1089 | case AH_ESP_V6_FLOW: | ||
| 1090 | case AH_V6_FLOW: | ||
| 1091 | case ESP_V6_FLOW: | ||
| 1092 | case SCTP_V6_FLOW: | ||
| 1093 | if (!(nfc->data & RXH_IP_SRC) || | ||
| 1094 | !(nfc->data & RXH_IP_DST) || | ||
| 1095 | (nfc->data & RXH_L4_B_0_1) || | ||
| 1096 | (nfc->data & RXH_L4_B_2_3)) | ||
| 1097 | return -EINVAL; | ||
| 1098 | break; | ||
| 1099 | default: | ||
| 1100 | return -EINVAL; | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | /* if we changed something we need to update flags */ | ||
| 1104 | if (flags != adapter->flags) { | ||
| 1105 | struct igc_hw *hw = &adapter->hw; | ||
| 1106 | u32 mrqc = rd32(IGC_MRQC); | ||
| 1107 | |||
| 1108 | if ((flags & UDP_RSS_FLAGS) && | ||
| 1109 | !(adapter->flags & UDP_RSS_FLAGS)) | ||
| 1110 | dev_err(&adapter->pdev->dev, | ||
| 1111 | "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n"); | ||
| 1112 | |||
| 1113 | adapter->flags = flags; | ||
| 1114 | |||
| 1115 | /* Perform hash on these packet types */ | ||
| 1116 | mrqc |= IGC_MRQC_RSS_FIELD_IPV4 | | ||
| 1117 | IGC_MRQC_RSS_FIELD_IPV4_TCP | | ||
| 1118 | IGC_MRQC_RSS_FIELD_IPV6 | | ||
| 1119 | IGC_MRQC_RSS_FIELD_IPV6_TCP; | ||
| 1120 | |||
| 1121 | mrqc &= ~(IGC_MRQC_RSS_FIELD_IPV4_UDP | | ||
| 1122 | IGC_MRQC_RSS_FIELD_IPV6_UDP); | ||
| 1123 | |||
| 1124 | if (flags & IGC_FLAG_RSS_FIELD_IPV4_UDP) | ||
| 1125 | mrqc |= IGC_MRQC_RSS_FIELD_IPV4_UDP; | ||
| 1126 | |||
| 1127 | if (flags & IGC_FLAG_RSS_FIELD_IPV6_UDP) | ||
| 1128 | mrqc |= IGC_MRQC_RSS_FIELD_IPV6_UDP; | ||
| 1129 | |||
| 1130 | wr32(IGC_MRQC, mrqc); | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | return 0; | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | static int igc_rxnfc_write_etype_filter(struct igc_adapter *adapter, | ||
| 1137 | struct igc_nfc_filter *input) | ||
| 1138 | { | ||
| 1139 | struct igc_hw *hw = &adapter->hw; | ||
| 1140 | u8 i; | ||
| 1141 | u32 etqf; | ||
| 1142 | u16 etype; | ||
| 1143 | |||
| 1144 | /* find an empty etype filter register */ | ||
| 1145 | for (i = 0; i < MAX_ETYPE_FILTER; ++i) { | ||
| 1146 | if (!adapter->etype_bitmap[i]) | ||
| 1147 | break; | ||
| 1148 | } | ||
| 1149 | if (i == MAX_ETYPE_FILTER) { | ||
| 1150 | dev_err(&adapter->pdev->dev, "ethtool -N: etype filters are all used.\n"); | ||
| 1151 | return -EINVAL; | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | adapter->etype_bitmap[i] = true; | ||
| 1155 | |||
| 1156 | etqf = rd32(IGC_ETQF(i)); | ||
| 1157 | etype = ntohs(input->filter.etype & ETHER_TYPE_FULL_MASK); | ||
| 1158 | |||
| 1159 | etqf |= IGC_ETQF_FILTER_ENABLE; | ||
| 1160 | etqf &= ~IGC_ETQF_ETYPE_MASK; | ||
| 1161 | etqf |= (etype & IGC_ETQF_ETYPE_MASK); | ||
| 1162 | |||
| 1163 | etqf &= ~IGC_ETQF_QUEUE_MASK; | ||
| 1164 | etqf |= ((input->action << IGC_ETQF_QUEUE_SHIFT) | ||
| 1165 | & IGC_ETQF_QUEUE_MASK); | ||
| 1166 | etqf |= IGC_ETQF_QUEUE_ENABLE; | ||
| 1167 | |||
| 1168 | wr32(IGC_ETQF(i), etqf); | ||
| 1169 | |||
| 1170 | input->etype_reg_index = i; | ||
| 1171 | |||
| 1172 | return 0; | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | static int igc_rxnfc_write_vlan_prio_filter(struct igc_adapter *adapter, | ||
| 1176 | struct igc_nfc_filter *input) | ||
| 1177 | { | ||
| 1178 | struct igc_hw *hw = &adapter->hw; | ||
| 1179 | u8 vlan_priority; | ||
| 1180 | u16 queue_index; | ||
| 1181 | u32 vlapqf; | ||
| 1182 | |||
| 1183 | vlapqf = rd32(IGC_VLAPQF); | ||
| 1184 | vlan_priority = (ntohs(input->filter.vlan_tci) & VLAN_PRIO_MASK) | ||
| 1185 | >> VLAN_PRIO_SHIFT; | ||
| 1186 | queue_index = (vlapqf >> (vlan_priority * 4)) & IGC_VLAPQF_QUEUE_MASK; | ||
| 1187 | |||
| 1188 | /* check whether this vlan prio is already set */ | ||
| 1189 | if (vlapqf & IGC_VLAPQF_P_VALID(vlan_priority) && | ||
| 1190 | queue_index != input->action) { | ||
| 1191 | dev_err(&adapter->pdev->dev, "ethtool rxnfc set vlan prio filter failed.\n"); | ||
| 1192 | return -EEXIST; | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | vlapqf |= IGC_VLAPQF_P_VALID(vlan_priority); | ||
| 1196 | vlapqf |= IGC_VLAPQF_QUEUE_SEL(vlan_priority, input->action); | ||
| 1197 | |||
| 1198 | wr32(IGC_VLAPQF, vlapqf); | ||
| 1199 | |||
| 1200 | return 0; | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input) | ||
| 1204 | { | ||
| 1205 | struct igc_hw *hw = &adapter->hw; | ||
| 1206 | int err = -EINVAL; | ||
| 1207 | |||
| 1208 | if (hw->mac.type == igc_i225 && | ||
| 1209 | !(input->filter.match_flags & ~IGC_FILTER_FLAG_SRC_MAC_ADDR)) { | ||
| 1210 | dev_err(&adapter->pdev->dev, | ||
| 1211 | "i225 doesn't support flow classification rules specifying only source addresses.\n"); | ||
| 1212 | return -EOPNOTSUPP; | ||
| 1213 | } | ||
| 1214 | |||
| 1215 | if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) { | ||
| 1216 | err = igc_rxnfc_write_etype_filter(adapter, input); | ||
| 1217 | if (err) | ||
| 1218 | return err; | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) { | ||
| 1222 | err = igc_add_mac_steering_filter(adapter, | ||
| 1223 | input->filter.dst_addr, | ||
| 1224 | input->action, 0); | ||
| 1225 | err = min_t(int, err, 0); | ||
| 1226 | if (err) | ||
| 1227 | return err; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) { | ||
| 1231 | err = igc_add_mac_steering_filter(adapter, | ||
| 1232 | input->filter.src_addr, | ||
| 1233 | input->action, | ||
| 1234 | IGC_MAC_STATE_SRC_ADDR); | ||
| 1235 | err = min_t(int, err, 0); | ||
| 1236 | if (err) | ||
| 1237 | return err; | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) | ||
| 1241 | err = igc_rxnfc_write_vlan_prio_filter(adapter, input); | ||
| 1242 | |||
| 1243 | return err; | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | static void igc_clear_etype_filter_regs(struct igc_adapter *adapter, | ||
| 1247 | u16 reg_index) | ||
| 1248 | { | ||
| 1249 | struct igc_hw *hw = &adapter->hw; | ||
| 1250 | u32 etqf = rd32(IGC_ETQF(reg_index)); | ||
| 1251 | |||
| 1252 | etqf &= ~IGC_ETQF_QUEUE_ENABLE; | ||
| 1253 | etqf &= ~IGC_ETQF_QUEUE_MASK; | ||
| 1254 | etqf &= ~IGC_ETQF_FILTER_ENABLE; | ||
| 1255 | |||
| 1256 | wr32(IGC_ETQF(reg_index), etqf); | ||
| 1257 | |||
| 1258 | adapter->etype_bitmap[reg_index] = false; | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | static void igc_clear_vlan_prio_filter(struct igc_adapter *adapter, | ||
| 1262 | u16 vlan_tci) | ||
| 1263 | { | ||
| 1264 | struct igc_hw *hw = &adapter->hw; | ||
| 1265 | u8 vlan_priority; | ||
| 1266 | u32 vlapqf; | ||
| 1267 | |||
| 1268 | vlan_priority = (vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; | ||
| 1269 | |||
| 1270 | vlapqf = rd32(IGC_VLAPQF); | ||
| 1271 | vlapqf &= ~IGC_VLAPQF_P_VALID(vlan_priority); | ||
| 1272 | vlapqf &= ~IGC_VLAPQF_QUEUE_SEL(vlan_priority, | ||
| 1273 | IGC_VLAPQF_QUEUE_MASK); | ||
| 1274 | |||
| 1275 | wr32(IGC_VLAPQF, vlapqf); | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input) | ||
| 1279 | { | ||
| 1280 | if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) | ||
| 1281 | igc_clear_etype_filter_regs(adapter, | ||
| 1282 | input->etype_reg_index); | ||
| 1283 | |||
| 1284 | if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) | ||
| 1285 | igc_clear_vlan_prio_filter(adapter, | ||
| 1286 | ntohs(input->filter.vlan_tci)); | ||
| 1287 | |||
| 1288 | if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) | ||
| 1289 | igc_del_mac_steering_filter(adapter, input->filter.src_addr, | ||
| 1290 | input->action, | ||
| 1291 | IGC_MAC_STATE_SRC_ADDR); | ||
| 1292 | |||
| 1293 | if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) | ||
| 1294 | igc_del_mac_steering_filter(adapter, input->filter.dst_addr, | ||
| 1295 | input->action, 0); | ||
| 1296 | |||
| 1297 | return 0; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | static int igc_update_ethtool_nfc_entry(struct igc_adapter *adapter, | ||
| 1301 | struct igc_nfc_filter *input, | ||
| 1302 | u16 sw_idx) | ||
| 1303 | { | ||
| 1304 | struct igc_nfc_filter *rule, *parent; | ||
| 1305 | int err = -EINVAL; | ||
| 1306 | |||
| 1307 | parent = NULL; | ||
| 1308 | rule = NULL; | ||
| 1309 | |||
| 1310 | hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) { | ||
| 1311 | /* hash found, or no matching entry */ | ||
| 1312 | if (rule->sw_idx >= sw_idx) | ||
| 1313 | break; | ||
| 1314 | parent = rule; | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | /* if there is an old rule occupying our place remove it */ | ||
| 1318 | if (rule && rule->sw_idx == sw_idx) { | ||
| 1319 | if (!input) | ||
| 1320 | err = igc_erase_filter(adapter, rule); | ||
| 1321 | |||
| 1322 | hlist_del(&rule->nfc_node); | ||
| 1323 | kfree(rule); | ||
| 1324 | adapter->nfc_filter_count--; | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | /* If no input this was a delete, err should be 0 if a rule was | ||
| 1328 | * successfully found and removed from the list else -EINVAL | ||
| 1329 | */ | ||
| 1330 | if (!input) | ||
| 1331 | return err; | ||
| 1332 | |||
| 1333 | /* initialize node */ | ||
| 1334 | INIT_HLIST_NODE(&input->nfc_node); | ||
| 1335 | |||
| 1336 | /* add filter to the list */ | ||
| 1337 | if (parent) | ||
| 1338 | hlist_add_behind(&input->nfc_node, &parent->nfc_node); | ||
| 1339 | else | ||
| 1340 | hlist_add_head(&input->nfc_node, &adapter->nfc_filter_list); | ||
| 1341 | |||
| 1342 | /* update counts */ | ||
| 1343 | adapter->nfc_filter_count++; | ||
| 1344 | |||
| 1345 | return 0; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter, | ||
| 1349 | struct ethtool_rxnfc *cmd) | ||
| 1350 | { | ||
| 1351 | struct net_device *netdev = adapter->netdev; | ||
| 1352 | struct ethtool_rx_flow_spec *fsp = | ||
| 1353 | (struct ethtool_rx_flow_spec *)&cmd->fs; | ||
| 1354 | struct igc_nfc_filter *input, *rule; | ||
| 1355 | int err = 0; | ||
| 1356 | |||
| 1357 | if (!(netdev->hw_features & NETIF_F_NTUPLE)) | ||
| 1358 | return -EOPNOTSUPP; | ||
| 1359 | |||
| 1360 | /* Don't allow programming if the action is a queue greater than | ||
| 1361 | * the number of online Rx queues. | ||
| 1362 | */ | ||
| 1363 | if (fsp->ring_cookie == RX_CLS_FLOW_DISC || | ||
| 1364 | fsp->ring_cookie >= adapter->num_rx_queues) { | ||
| 1365 | dev_err(&adapter->pdev->dev, "ethtool -N: The specified action is invalid\n"); | ||
| 1366 | return -EINVAL; | ||
| 1367 | } | ||
| 1368 | |||
| 1369 | /* Don't allow indexes to exist outside of available space */ | ||
| 1370 | if (fsp->location >= IGC_MAX_RXNFC_FILTERS) { | ||
| 1371 | dev_err(&adapter->pdev->dev, "Location out of range\n"); | ||
| 1372 | return -EINVAL; | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | if ((fsp->flow_type & ~FLOW_EXT) != ETHER_FLOW) | ||
| 1376 | return -EINVAL; | ||
| 1377 | |||
| 1378 | input = kzalloc(sizeof(*input), GFP_KERNEL); | ||
| 1379 | if (!input) | ||
| 1380 | return -ENOMEM; | ||
| 1381 | |||
| 1382 | if (fsp->m_u.ether_spec.h_proto == ETHER_TYPE_FULL_MASK) { | ||
| 1383 | input->filter.etype = fsp->h_u.ether_spec.h_proto; | ||
| 1384 | input->filter.match_flags = IGC_FILTER_FLAG_ETHER_TYPE; | ||
| 1385 | } | ||
| 1386 | |||
| 1387 | /* Only support matching addresses by the full mask */ | ||
| 1388 | if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_source)) { | ||
| 1389 | input->filter.match_flags |= IGC_FILTER_FLAG_SRC_MAC_ADDR; | ||
| 1390 | ether_addr_copy(input->filter.src_addr, | ||
| 1391 | fsp->h_u.ether_spec.h_source); | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | /* Only support matching addresses by the full mask */ | ||
| 1395 | if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_dest)) { | ||
| 1396 | input->filter.match_flags |= IGC_FILTER_FLAG_DST_MAC_ADDR; | ||
| 1397 | ether_addr_copy(input->filter.dst_addr, | ||
| 1398 | fsp->h_u.ether_spec.h_dest); | ||
| 1399 | } | ||
| 1400 | |||
| 1401 | if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) { | ||
| 1402 | if (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) { | ||
| 1403 | err = -EINVAL; | ||
| 1404 | goto err_out; | ||
| 1405 | } | ||
| 1406 | input->filter.vlan_tci = fsp->h_ext.vlan_tci; | ||
| 1407 | input->filter.match_flags |= IGC_FILTER_FLAG_VLAN_TCI; | ||
| 1408 | } | ||
| 1409 | |||
| 1410 | input->action = fsp->ring_cookie; | ||
| 1411 | input->sw_idx = fsp->location; | ||
| 1412 | |||
| 1413 | spin_lock(&adapter->nfc_lock); | ||
| 1414 | |||
| 1415 | hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) { | ||
| 1416 | if (!memcmp(&input->filter, &rule->filter, | ||
| 1417 | sizeof(input->filter))) { | ||
| 1418 | err = -EEXIST; | ||
| 1419 | dev_err(&adapter->pdev->dev, | ||
| 1420 | "ethtool: this filter is already set\n"); | ||
| 1421 | goto err_out_w_lock; | ||
| 1422 | } | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | err = igc_add_filter(adapter, input); | ||
| 1426 | if (err) | ||
| 1427 | goto err_out_w_lock; | ||
| 1428 | |||
| 1429 | igc_update_ethtool_nfc_entry(adapter, input, input->sw_idx); | ||
| 1430 | |||
| 1431 | spin_unlock(&adapter->nfc_lock); | ||
| 1432 | return 0; | ||
| 1433 | |||
| 1434 | err_out_w_lock: | ||
| 1435 | spin_unlock(&adapter->nfc_lock); | ||
| 1436 | err_out: | ||
| 1437 | kfree(input); | ||
| 1438 | return err; | ||
| 1439 | } | ||
| 1440 | |||
| 1441 | static int igc_del_ethtool_nfc_entry(struct igc_adapter *adapter, | ||
| 1442 | struct ethtool_rxnfc *cmd) | ||
| 1443 | { | ||
| 1444 | struct ethtool_rx_flow_spec *fsp = | ||
| 1445 | (struct ethtool_rx_flow_spec *)&cmd->fs; | ||
| 1446 | int err; | ||
| 1447 | |||
| 1448 | spin_lock(&adapter->nfc_lock); | ||
| 1449 | err = igc_update_ethtool_nfc_entry(adapter, NULL, fsp->location); | ||
| 1450 | spin_unlock(&adapter->nfc_lock); | ||
| 1451 | |||
| 1452 | return err; | ||
| 1453 | } | ||
| 1454 | |||
| 1455 | static int igc_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) | ||
| 1456 | { | ||
| 1457 | struct igc_adapter *adapter = netdev_priv(dev); | ||
| 1458 | int ret = -EOPNOTSUPP; | ||
| 1459 | |||
| 1460 | switch (cmd->cmd) { | ||
| 1461 | case ETHTOOL_SRXFH: | ||
| 1462 | ret = igc_set_rss_hash_opt(adapter, cmd); | ||
| 1463 | break; | ||
| 1464 | case ETHTOOL_SRXCLSRLINS: | ||
| 1465 | ret = igc_add_ethtool_nfc_entry(adapter, cmd); | ||
| 1466 | break; | ||
| 1467 | case ETHTOOL_SRXCLSRLDEL: | ||
| 1468 | ret = igc_del_ethtool_nfc_entry(adapter, cmd); | ||
| 1469 | default: | ||
| 1470 | break; | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | return ret; | ||
| 1474 | } | ||
| 1475 | |||
| 646 | void igc_write_rss_indir_tbl(struct igc_adapter *adapter) | 1476 | void igc_write_rss_indir_tbl(struct igc_adapter *adapter) |
| 647 | { | 1477 | { |
| 648 | struct igc_hw *hw = &adapter->hw; | 1478 | struct igc_hw *hw = &adapter->hw; |
| @@ -885,17 +1715,13 @@ static int igc_get_link_ksettings(struct net_device *netdev, | |||
| 885 | if (hw->mac.type == igc_i225 && | 1715 | if (hw->mac.type == igc_i225 && |
| 886 | (status & IGC_STATUS_SPEED_2500)) { | 1716 | (status & IGC_STATUS_SPEED_2500)) { |
| 887 | speed = SPEED_2500; | 1717 | speed = SPEED_2500; |
| 888 | hw_dbg("2500 Mbs, "); | ||
| 889 | } else { | 1718 | } else { |
| 890 | speed = SPEED_1000; | 1719 | speed = SPEED_1000; |
| 891 | hw_dbg("1000 Mbs, "); | ||
| 892 | } | 1720 | } |
| 893 | } else if (status & IGC_STATUS_SPEED_100) { | 1721 | } else if (status & IGC_STATUS_SPEED_100) { |
| 894 | speed = SPEED_100; | 1722 | speed = SPEED_100; |
| 895 | hw_dbg("100 Mbs, "); | ||
| 896 | } else { | 1723 | } else { |
| 897 | speed = SPEED_10; | 1724 | speed = SPEED_10; |
| 898 | hw_dbg("10 Mbs, "); | ||
| 899 | } | 1725 | } |
| 900 | if ((status & IGC_STATUS_FD) || | 1726 | if ((status & IGC_STATUS_FD) || |
| 901 | hw->phy.media_type != igc_media_type_copper) | 1727 | hw->phy.media_type != igc_media_type_copper) |
| @@ -1011,8 +1837,13 @@ static const struct ethtool_ops igc_ethtool_ops = { | |||
| 1011 | .set_ringparam = igc_set_ringparam, | 1837 | .set_ringparam = igc_set_ringparam, |
| 1012 | .get_pauseparam = igc_get_pauseparam, | 1838 | .get_pauseparam = igc_get_pauseparam, |
| 1013 | .set_pauseparam = igc_set_pauseparam, | 1839 | .set_pauseparam = igc_set_pauseparam, |
| 1840 | .get_strings = igc_get_strings, | ||
| 1841 | .get_sset_count = igc_get_sset_count, | ||
| 1842 | .get_ethtool_stats = igc_get_ethtool_stats, | ||
| 1014 | .get_coalesce = igc_get_coalesce, | 1843 | .get_coalesce = igc_get_coalesce, |
| 1015 | .set_coalesce = igc_set_coalesce, | 1844 | .set_coalesce = igc_set_coalesce, |
| 1845 | .get_rxnfc = igc_get_rxnfc, | ||
| 1846 | .set_rxnfc = igc_set_rxnfc, | ||
| 1016 | .get_rxfh_indir_size = igc_get_rxfh_indir_size, | 1847 | .get_rxfh_indir_size = igc_get_rxfh_indir_size, |
| 1017 | .get_rxfh = igc_get_rxfh, | 1848 | .get_rxfh = igc_get_rxfh, |
| 1018 | .set_rxfh = igc_set_rxfh, | 1849 | .set_rxfh = igc_set_rxfh, |
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 87a11879bf2d..a883b3f357e7 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c | |||
| @@ -620,6 +620,55 @@ static void igc_configure_tx(struct igc_adapter *adapter) | |||
| 620 | */ | 620 | */ |
| 621 | static void igc_setup_mrqc(struct igc_adapter *adapter) | 621 | static void igc_setup_mrqc(struct igc_adapter *adapter) |
| 622 | { | 622 | { |
| 623 | struct igc_hw *hw = &adapter->hw; | ||
| 624 | u32 j, num_rx_queues; | ||
| 625 | u32 mrqc, rxcsum; | ||
| 626 | u32 rss_key[10]; | ||
| 627 | |||
| 628 | netdev_rss_key_fill(rss_key, sizeof(rss_key)); | ||
| 629 | for (j = 0; j < 10; j++) | ||
| 630 | wr32(IGC_RSSRK(j), rss_key[j]); | ||
| 631 | |||
| 632 | num_rx_queues = adapter->rss_queues; | ||
| 633 | |||
| 634 | if (adapter->rss_indir_tbl_init != num_rx_queues) { | ||
| 635 | for (j = 0; j < IGC_RETA_SIZE; j++) | ||
| 636 | adapter->rss_indir_tbl[j] = | ||
| 637 | (j * num_rx_queues) / IGC_RETA_SIZE; | ||
| 638 | adapter->rss_indir_tbl_init = num_rx_queues; | ||
| 639 | } | ||
| 640 | igc_write_rss_indir_tbl(adapter); | ||
| 641 | |||
| 642 | /* Disable raw packet checksumming so that RSS hash is placed in | ||
| 643 | * descriptor on writeback. No need to enable TCP/UDP/IP checksum | ||
| 644 | * offloads as they are enabled by default | ||
| 645 | */ | ||
| 646 | rxcsum = rd32(IGC_RXCSUM); | ||
| 647 | rxcsum |= IGC_RXCSUM_PCSD; | ||
| 648 | |||
| 649 | /* Enable Receive Checksum Offload for SCTP */ | ||
| 650 | rxcsum |= IGC_RXCSUM_CRCOFL; | ||
| 651 | |||
| 652 | /* Don't need to set TUOFL or IPOFL, they default to 1 */ | ||
| 653 | wr32(IGC_RXCSUM, rxcsum); | ||
| 654 | |||
| 655 | /* Generate RSS hash based on packet types, TCP/UDP | ||
| 656 | * port numbers and/or IPv4/v6 src and dst addresses | ||
| 657 | */ | ||
| 658 | mrqc = IGC_MRQC_RSS_FIELD_IPV4 | | ||
| 659 | IGC_MRQC_RSS_FIELD_IPV4_TCP | | ||
| 660 | IGC_MRQC_RSS_FIELD_IPV6 | | ||
| 661 | IGC_MRQC_RSS_FIELD_IPV6_TCP | | ||
| 662 | IGC_MRQC_RSS_FIELD_IPV6_TCP_EX; | ||
| 663 | |||
| 664 | if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV4_UDP) | ||
| 665 | mrqc |= IGC_MRQC_RSS_FIELD_IPV4_UDP; | ||
| 666 | if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV6_UDP) | ||
| 667 | mrqc |= IGC_MRQC_RSS_FIELD_IPV6_UDP; | ||
| 668 | |||
| 669 | mrqc |= IGC_MRQC_ENABLE_RSS_MQ; | ||
| 670 | |||
| 671 | wr32(IGC_MRQC, mrqc); | ||
| 623 | } | 672 | } |
| 624 | 673 | ||
| 625 | /** | 674 | /** |
| @@ -1738,12 +1787,200 @@ void igc_up(struct igc_adapter *adapter) | |||
| 1738 | * igc_update_stats - Update the board statistics counters | 1787 | * igc_update_stats - Update the board statistics counters |
| 1739 | * @adapter: board private structure | 1788 | * @adapter: board private structure |
| 1740 | */ | 1789 | */ |
| 1741 | static void igc_update_stats(struct igc_adapter *adapter) | 1790 | void igc_update_stats(struct igc_adapter *adapter) |
| 1742 | { | 1791 | { |
| 1792 | struct rtnl_link_stats64 *net_stats = &adapter->stats64; | ||
| 1793 | struct pci_dev *pdev = adapter->pdev; | ||
| 1794 | struct igc_hw *hw = &adapter->hw; | ||
| 1795 | u64 _bytes, _packets; | ||
| 1796 | u64 bytes, packets; | ||
| 1797 | unsigned int start; | ||
| 1798 | u32 mpc; | ||
| 1799 | int i; | ||
| 1800 | |||
| 1801 | /* Prevent stats update while adapter is being reset, or if the pci | ||
| 1802 | * connection is down. | ||
| 1803 | */ | ||
| 1804 | if (adapter->link_speed == 0) | ||
| 1805 | return; | ||
| 1806 | if (pci_channel_offline(pdev)) | ||
| 1807 | return; | ||
| 1808 | |||
| 1809 | packets = 0; | ||
| 1810 | bytes = 0; | ||
| 1811 | |||
| 1812 | rcu_read_lock(); | ||
| 1813 | for (i = 0; i < adapter->num_rx_queues; i++) { | ||
| 1814 | struct igc_ring *ring = adapter->rx_ring[i]; | ||
| 1815 | u32 rqdpc = rd32(IGC_RQDPC(i)); | ||
| 1816 | |||
| 1817 | if (hw->mac.type >= igc_i225) | ||
| 1818 | wr32(IGC_RQDPC(i), 0); | ||
| 1819 | |||
| 1820 | if (rqdpc) { | ||
| 1821 | ring->rx_stats.drops += rqdpc; | ||
| 1822 | net_stats->rx_fifo_errors += rqdpc; | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | do { | ||
| 1826 | start = u64_stats_fetch_begin_irq(&ring->rx_syncp); | ||
| 1827 | _bytes = ring->rx_stats.bytes; | ||
| 1828 | _packets = ring->rx_stats.packets; | ||
| 1829 | } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); | ||
| 1830 | bytes += _bytes; | ||
| 1831 | packets += _packets; | ||
| 1832 | } | ||
| 1833 | |||
| 1834 | net_stats->rx_bytes = bytes; | ||
| 1835 | net_stats->rx_packets = packets; | ||
| 1836 | |||
| 1837 | packets = 0; | ||
| 1838 | bytes = 0; | ||
| 1839 | for (i = 0; i < adapter->num_tx_queues; i++) { | ||
| 1840 | struct igc_ring *ring = adapter->tx_ring[i]; | ||
| 1841 | |||
| 1842 | do { | ||
| 1843 | start = u64_stats_fetch_begin_irq(&ring->tx_syncp); | ||
| 1844 | _bytes = ring->tx_stats.bytes; | ||
| 1845 | _packets = ring->tx_stats.packets; | ||
| 1846 | } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); | ||
| 1847 | bytes += _bytes; | ||
| 1848 | packets += _packets; | ||
| 1849 | } | ||
| 1850 | net_stats->tx_bytes = bytes; | ||
| 1851 | net_stats->tx_packets = packets; | ||
| 1852 | rcu_read_unlock(); | ||
| 1853 | |||
| 1854 | /* read stats registers */ | ||
| 1855 | adapter->stats.crcerrs += rd32(IGC_CRCERRS); | ||
| 1856 | adapter->stats.gprc += rd32(IGC_GPRC); | ||
| 1857 | adapter->stats.gorc += rd32(IGC_GORCL); | ||
| 1858 | rd32(IGC_GORCH); /* clear GORCL */ | ||
| 1859 | adapter->stats.bprc += rd32(IGC_BPRC); | ||
| 1860 | adapter->stats.mprc += rd32(IGC_MPRC); | ||
| 1861 | adapter->stats.roc += rd32(IGC_ROC); | ||
| 1862 | |||
| 1863 | adapter->stats.prc64 += rd32(IGC_PRC64); | ||
| 1864 | adapter->stats.prc127 += rd32(IGC_PRC127); | ||
| 1865 | adapter->stats.prc255 += rd32(IGC_PRC255); | ||
| 1866 | adapter->stats.prc511 += rd32(IGC_PRC511); | ||
| 1867 | adapter->stats.prc1023 += rd32(IGC_PRC1023); | ||
| 1868 | adapter->stats.prc1522 += rd32(IGC_PRC1522); | ||
| 1869 | adapter->stats.symerrs += rd32(IGC_SYMERRS); | ||
| 1870 | adapter->stats.sec += rd32(IGC_SEC); | ||
| 1871 | |||
| 1872 | mpc = rd32(IGC_MPC); | ||
| 1873 | adapter->stats.mpc += mpc; | ||
| 1874 | net_stats->rx_fifo_errors += mpc; | ||
| 1875 | adapter->stats.scc += rd32(IGC_SCC); | ||
| 1876 | adapter->stats.ecol += rd32(IGC_ECOL); | ||
| 1877 | adapter->stats.mcc += rd32(IGC_MCC); | ||
| 1878 | adapter->stats.latecol += rd32(IGC_LATECOL); | ||
| 1879 | adapter->stats.dc += rd32(IGC_DC); | ||
| 1880 | adapter->stats.rlec += rd32(IGC_RLEC); | ||
| 1881 | adapter->stats.xonrxc += rd32(IGC_XONRXC); | ||
| 1882 | adapter->stats.xontxc += rd32(IGC_XONTXC); | ||
| 1883 | adapter->stats.xoffrxc += rd32(IGC_XOFFRXC); | ||
| 1884 | adapter->stats.xofftxc += rd32(IGC_XOFFTXC); | ||
| 1885 | adapter->stats.fcruc += rd32(IGC_FCRUC); | ||
| 1886 | adapter->stats.gptc += rd32(IGC_GPTC); | ||
| 1887 | adapter->stats.gotc += rd32(IGC_GOTCL); | ||
| 1888 | rd32(IGC_GOTCH); /* clear GOTCL */ | ||
| 1889 | adapter->stats.rnbc += rd32(IGC_RNBC); | ||
| 1890 | adapter->stats.ruc += rd32(IGC_RUC); | ||
| 1891 | adapter->stats.rfc += rd32(IGC_RFC); | ||
| 1892 | adapter->stats.rjc += rd32(IGC_RJC); | ||
| 1893 | adapter->stats.tor += rd32(IGC_TORH); | ||
| 1894 | adapter->stats.tot += rd32(IGC_TOTH); | ||
| 1895 | adapter->stats.tpr += rd32(IGC_TPR); | ||
| 1896 | |||
| 1897 | adapter->stats.ptc64 += rd32(IGC_PTC64); | ||
| 1898 | adapter->stats.ptc127 += rd32(IGC_PTC127); | ||
| 1899 | adapter->stats.ptc255 += rd32(IGC_PTC255); | ||
| 1900 | adapter->stats.ptc511 += rd32(IGC_PTC511); | ||
| 1901 | adapter->stats.ptc1023 += rd32(IGC_PTC1023); | ||
| 1902 | adapter->stats.ptc1522 += rd32(IGC_PTC1522); | ||
| 1903 | |||
| 1904 | adapter->stats.mptc += rd32(IGC_MPTC); | ||
| 1905 | adapter->stats.bptc += rd32(IGC_BPTC); | ||
| 1906 | |||
| 1907 | adapter->stats.tpt += rd32(IGC_TPT); | ||
| 1908 | adapter->stats.colc += rd32(IGC_COLC); | ||
| 1909 | |||
| 1910 | adapter->stats.algnerrc += rd32(IGC_ALGNERRC); | ||
| 1911 | |||
| 1912 | adapter->stats.tsctc += rd32(IGC_TSCTC); | ||
| 1913 | adapter->stats.tsctfc += rd32(IGC_TSCTFC); | ||
| 1914 | |||
| 1915 | adapter->stats.iac += rd32(IGC_IAC); | ||
| 1916 | adapter->stats.icrxoc += rd32(IGC_ICRXOC); | ||
| 1917 | adapter->stats.icrxptc += rd32(IGC_ICRXPTC); | ||
| 1918 | adapter->stats.icrxatc += rd32(IGC_ICRXATC); | ||
| 1919 | adapter->stats.ictxptc += rd32(IGC_ICTXPTC); | ||
| 1920 | adapter->stats.ictxatc += rd32(IGC_ICTXATC); | ||
| 1921 | adapter->stats.ictxqec += rd32(IGC_ICTXQEC); | ||
| 1922 | adapter->stats.ictxqmtc += rd32(IGC_ICTXQMTC); | ||
| 1923 | adapter->stats.icrxdmtc += rd32(IGC_ICRXDMTC); | ||
| 1924 | |||
| 1925 | /* Fill out the OS statistics structure */ | ||
| 1926 | net_stats->multicast = adapter->stats.mprc; | ||
| 1927 | net_stats->collisions = adapter->stats.colc; | ||
| 1928 | |||
| 1929 | /* Rx Errors */ | ||
| 1930 | |||
| 1931 | /* RLEC on some newer hardware can be incorrect so build | ||
| 1932 | * our own version based on RUC and ROC | ||
| 1933 | */ | ||
| 1934 | net_stats->rx_errors = adapter->stats.rxerrc + | ||
| 1935 | adapter->stats.crcerrs + adapter->stats.algnerrc + | ||
| 1936 | adapter->stats.ruc + adapter->stats.roc + | ||
| 1937 | adapter->stats.cexterr; | ||
| 1938 | net_stats->rx_length_errors = adapter->stats.ruc + | ||
| 1939 | adapter->stats.roc; | ||
| 1940 | net_stats->rx_crc_errors = adapter->stats.crcerrs; | ||
| 1941 | net_stats->rx_frame_errors = adapter->stats.algnerrc; | ||
| 1942 | net_stats->rx_missed_errors = adapter->stats.mpc; | ||
| 1943 | |||
| 1944 | /* Tx Errors */ | ||
| 1945 | net_stats->tx_errors = adapter->stats.ecol + | ||
| 1946 | adapter->stats.latecol; | ||
| 1947 | net_stats->tx_aborted_errors = adapter->stats.ecol; | ||
| 1948 | net_stats->tx_window_errors = adapter->stats.latecol; | ||
| 1949 | net_stats->tx_carrier_errors = adapter->stats.tncrs; | ||
| 1950 | |||
| 1951 | /* Tx Dropped needs to be maintained elsewhere */ | ||
| 1952 | |||
| 1953 | /* Management Stats */ | ||
| 1954 | adapter->stats.mgptc += rd32(IGC_MGTPTC); | ||
| 1955 | adapter->stats.mgprc += rd32(IGC_MGTPRC); | ||
| 1956 | adapter->stats.mgpdc += rd32(IGC_MGTPDC); | ||
| 1743 | } | 1957 | } |
| 1744 | 1958 | ||
| 1745 | static void igc_nfc_filter_exit(struct igc_adapter *adapter) | 1959 | static void igc_nfc_filter_exit(struct igc_adapter *adapter) |
| 1746 | { | 1960 | { |
| 1961 | struct igc_nfc_filter *rule; | ||
| 1962 | |||
| 1963 | spin_lock(&adapter->nfc_lock); | ||
| 1964 | |||
| 1965 | hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) | ||
| 1966 | igc_erase_filter(adapter, rule); | ||
| 1967 | |||
| 1968 | hlist_for_each_entry(rule, &adapter->cls_flower_list, nfc_node) | ||
| 1969 | igc_erase_filter(adapter, rule); | ||
| 1970 | |||
| 1971 | spin_unlock(&adapter->nfc_lock); | ||
| 1972 | } | ||
| 1973 | |||
| 1974 | static void igc_nfc_filter_restore(struct igc_adapter *adapter) | ||
| 1975 | { | ||
| 1976 | struct igc_nfc_filter *rule; | ||
| 1977 | |||
| 1978 | spin_lock(&adapter->nfc_lock); | ||
| 1979 | |||
| 1980 | hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) | ||
| 1981 | igc_add_filter(adapter, rule); | ||
| 1982 | |||
| 1983 | spin_unlock(&adapter->nfc_lock); | ||
| 1747 | } | 1984 | } |
| 1748 | 1985 | ||
| 1749 | /** | 1986 | /** |
| @@ -1890,6 +2127,86 @@ static struct net_device_stats *igc_get_stats(struct net_device *netdev) | |||
| 1890 | return &netdev->stats; | 2127 | return &netdev->stats; |
| 1891 | } | 2128 | } |
| 1892 | 2129 | ||
| 2130 | static netdev_features_t igc_fix_features(struct net_device *netdev, | ||
| 2131 | netdev_features_t features) | ||
| 2132 | { | ||
| 2133 | /* Since there is no support for separate Rx/Tx vlan accel | ||
| 2134 | * enable/disable make sure Tx flag is always in same state as Rx. | ||
| 2135 | */ | ||
| 2136 | if (features & NETIF_F_HW_VLAN_CTAG_RX) | ||
| 2137 | features |= NETIF_F_HW_VLAN_CTAG_TX; | ||
| 2138 | else | ||
| 2139 | features &= ~NETIF_F_HW_VLAN_CTAG_TX; | ||
| 2140 | |||
| 2141 | return features; | ||
| 2142 | } | ||
| 2143 | |||
| 2144 | static int igc_set_features(struct net_device *netdev, | ||
| 2145 | netdev_features_t features) | ||
| 2146 | { | ||
| 2147 | netdev_features_t changed = netdev->features ^ features; | ||
| 2148 | struct igc_adapter *adapter = netdev_priv(netdev); | ||
| 2149 | |||
| 2150 | /* Add VLAN support */ | ||
| 2151 | if (!(changed & (NETIF_F_RXALL | NETIF_F_NTUPLE))) | ||
| 2152 | return 0; | ||
| 2153 | |||
| 2154 | if (!(features & NETIF_F_NTUPLE)) { | ||
| 2155 | struct hlist_node *node2; | ||
| 2156 | struct igc_nfc_filter *rule; | ||
| 2157 | |||
| 2158 | spin_lock(&adapter->nfc_lock); | ||
| 2159 | hlist_for_each_entry_safe(rule, node2, | ||
| 2160 | &adapter->nfc_filter_list, nfc_node) { | ||
| 2161 | igc_erase_filter(adapter, rule); | ||
| 2162 | hlist_del(&rule->nfc_node); | ||
| 2163 | kfree(rule); | ||
| 2164 | } | ||
| 2165 | spin_unlock(&adapter->nfc_lock); | ||
| 2166 | adapter->nfc_filter_count = 0; | ||
| 2167 | } | ||
| 2168 | |||
| 2169 | netdev->features = features; | ||
| 2170 | |||
| 2171 | if (netif_running(netdev)) | ||
| 2172 | igc_reinit_locked(adapter); | ||
| 2173 | else | ||
| 2174 | igc_reset(adapter); | ||
| 2175 | |||
| 2176 | return 1; | ||
| 2177 | } | ||
| 2178 | |||
| 2179 | static netdev_features_t | ||
| 2180 | igc_features_check(struct sk_buff *skb, struct net_device *dev, | ||
| 2181 | netdev_features_t features) | ||
| 2182 | { | ||
| 2183 | unsigned int network_hdr_len, mac_hdr_len; | ||
| 2184 | |||
| 2185 | /* Make certain the headers can be described by a context descriptor */ | ||
| 2186 | mac_hdr_len = skb_network_header(skb) - skb->data; | ||
| 2187 | if (unlikely(mac_hdr_len > IGC_MAX_MAC_HDR_LEN)) | ||
| 2188 | return features & ~(NETIF_F_HW_CSUM | | ||
| 2189 | NETIF_F_SCTP_CRC | | ||
| 2190 | NETIF_F_HW_VLAN_CTAG_TX | | ||
| 2191 | NETIF_F_TSO | | ||
| 2192 | NETIF_F_TSO6); | ||
| 2193 | |||
| 2194 | network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb); | ||
| 2195 | if (unlikely(network_hdr_len > IGC_MAX_NETWORK_HDR_LEN)) | ||
| 2196 | return features & ~(NETIF_F_HW_CSUM | | ||
| 2197 | NETIF_F_SCTP_CRC | | ||
| 2198 | NETIF_F_TSO | | ||
| 2199 | NETIF_F_TSO6); | ||
| 2200 | |||
| 2201 | /* We can only support IPv4 TSO in tunnels if we can mangle the | ||
| 2202 | * inner IP ID field, so strip TSO if MANGLEID is not supported. | ||
| 2203 | */ | ||
| 2204 | if (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID)) | ||
| 2205 | features &= ~NETIF_F_TSO; | ||
| 2206 | |||
| 2207 | return features; | ||
| 2208 | } | ||
| 2209 | |||
| 1893 | /** | 2210 | /** |
| 1894 | * igc_configure - configure the hardware for RX and TX | 2211 | * igc_configure - configure the hardware for RX and TX |
| 1895 | * @adapter: private board structure | 2212 | * @adapter: private board structure |
| @@ -1906,6 +2223,7 @@ static void igc_configure(struct igc_adapter *adapter) | |||
| 1906 | igc_setup_mrqc(adapter); | 2223 | igc_setup_mrqc(adapter); |
| 1907 | igc_setup_rctl(adapter); | 2224 | igc_setup_rctl(adapter); |
| 1908 | 2225 | ||
| 2226 | igc_nfc_filter_restore(adapter); | ||
| 1909 | igc_configure_tx(adapter); | 2227 | igc_configure_tx(adapter); |
| 1910 | igc_configure_rx(adapter); | 2228 | igc_configure_rx(adapter); |
| 1911 | 2229 | ||
| @@ -1967,6 +2285,127 @@ static void igc_set_default_mac_filter(struct igc_adapter *adapter) | |||
| 1967 | igc_rar_set_index(adapter, 0); | 2285 | igc_rar_set_index(adapter, 0); |
| 1968 | } | 2286 | } |
| 1969 | 2287 | ||
| 2288 | /* If the filter to be added and an already existing filter express | ||
| 2289 | * the same address and address type, it should be possible to only | ||
| 2290 | * override the other configurations, for example the queue to steer | ||
| 2291 | * traffic. | ||
| 2292 | */ | ||
| 2293 | static bool igc_mac_entry_can_be_used(const struct igc_mac_addr *entry, | ||
| 2294 | const u8 *addr, const u8 flags) | ||
| 2295 | { | ||
| 2296 | if (!(entry->state & IGC_MAC_STATE_IN_USE)) | ||
| 2297 | return true; | ||
| 2298 | |||
| 2299 | if ((entry->state & IGC_MAC_STATE_SRC_ADDR) != | ||
| 2300 | (flags & IGC_MAC_STATE_SRC_ADDR)) | ||
| 2301 | return false; | ||
| 2302 | |||
| 2303 | if (!ether_addr_equal(addr, entry->addr)) | ||
| 2304 | return false; | ||
| 2305 | |||
| 2306 | return true; | ||
| 2307 | } | ||
| 2308 | |||
| 2309 | /* Add a MAC filter for 'addr' directing matching traffic to 'queue', | ||
| 2310 | * 'flags' is used to indicate what kind of match is made, match is by | ||
| 2311 | * default for the destination address, if matching by source address | ||
| 2312 | * is desired the flag IGC_MAC_STATE_SRC_ADDR can be used. | ||
| 2313 | */ | ||
| 2314 | static int igc_add_mac_filter_flags(struct igc_adapter *adapter, | ||
| 2315 | const u8 *addr, const u8 queue, | ||
| 2316 | const u8 flags) | ||
| 2317 | { | ||
| 2318 | struct igc_hw *hw = &adapter->hw; | ||
| 2319 | int rar_entries = hw->mac.rar_entry_count; | ||
| 2320 | int i; | ||
| 2321 | |||
| 2322 | if (is_zero_ether_addr(addr)) | ||
| 2323 | return -EINVAL; | ||
| 2324 | |||
| 2325 | /* Search for the first empty entry in the MAC table. | ||
| 2326 | * Do not touch entries at the end of the table reserved for the VF MAC | ||
| 2327 | * addresses. | ||
| 2328 | */ | ||
| 2329 | for (i = 0; i < rar_entries; i++) { | ||
| 2330 | if (!igc_mac_entry_can_be_used(&adapter->mac_table[i], | ||
| 2331 | addr, flags)) | ||
| 2332 | continue; | ||
| 2333 | |||
| 2334 | ether_addr_copy(adapter->mac_table[i].addr, addr); | ||
| 2335 | adapter->mac_table[i].queue = queue; | ||
| 2336 | adapter->mac_table[i].state |= IGC_MAC_STATE_IN_USE | flags; | ||
| 2337 | |||
| 2338 | igc_rar_set_index(adapter, i); | ||
| 2339 | return i; | ||
| 2340 | } | ||
| 2341 | |||
| 2342 | return -ENOSPC; | ||
| 2343 | } | ||
| 2344 | |||
| 2345 | int igc_add_mac_steering_filter(struct igc_adapter *adapter, | ||
| 2346 | const u8 *addr, u8 queue, u8 flags) | ||
| 2347 | { | ||
| 2348 | return igc_add_mac_filter_flags(adapter, addr, queue, | ||
| 2349 | IGC_MAC_STATE_QUEUE_STEERING | flags); | ||
| 2350 | } | ||
| 2351 | |||
| 2352 | /* Remove a MAC filter for 'addr' directing matching traffic to | ||
| 2353 | * 'queue', 'flags' is used to indicate what kind of match need to be | ||
| 2354 | * removed, match is by default for the destination address, if | ||
| 2355 | * matching by source address is to be removed the flag | ||
| 2356 | * IGC_MAC_STATE_SRC_ADDR can be used. | ||
| 2357 | */ | ||
| 2358 | static int igc_del_mac_filter_flags(struct igc_adapter *adapter, | ||
| 2359 | const u8 *addr, const u8 queue, | ||
| 2360 | const u8 flags) | ||
| 2361 | { | ||
| 2362 | struct igc_hw *hw = &adapter->hw; | ||
| 2363 | int rar_entries = hw->mac.rar_entry_count; | ||
| 2364 | int i; | ||
| 2365 | |||
| 2366 | if (is_zero_ether_addr(addr)) | ||
| 2367 | return -EINVAL; | ||
| 2368 | |||
| 2369 | /* Search for matching entry in the MAC table based on given address | ||
| 2370 | * and queue. Do not touch entries at the end of the table reserved | ||
| 2371 | * for the VF MAC addresses. | ||
| 2372 | */ | ||
| 2373 | for (i = 0; i < rar_entries; i++) { | ||
| 2374 | if (!(adapter->mac_table[i].state & IGC_MAC_STATE_IN_USE)) | ||
| 2375 | continue; | ||
| 2376 | if ((adapter->mac_table[i].state & flags) != flags) | ||
| 2377 | continue; | ||
| 2378 | if (adapter->mac_table[i].queue != queue) | ||
| 2379 | continue; | ||
| 2380 | if (!ether_addr_equal(adapter->mac_table[i].addr, addr)) | ||
| 2381 | continue; | ||
| 2382 | |||
| 2383 | /* When a filter for the default address is "deleted", | ||
| 2384 | * we return it to its initial configuration | ||
| 2385 | */ | ||
| 2386 | if (adapter->mac_table[i].state & IGC_MAC_STATE_DEFAULT) { | ||
| 2387 | adapter->mac_table[i].state = | ||
| 2388 | IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE; | ||
| 2389 | } else { | ||
| 2390 | adapter->mac_table[i].state = 0; | ||
| 2391 | adapter->mac_table[i].queue = 0; | ||
| 2392 | memset(adapter->mac_table[i].addr, 0, ETH_ALEN); | ||
| 2393 | } | ||
| 2394 | |||
| 2395 | igc_rar_set_index(adapter, i); | ||
| 2396 | return 0; | ||
| 2397 | } | ||
| 2398 | |||
| 2399 | return -ENOENT; | ||
| 2400 | } | ||
| 2401 | |||
| 2402 | int igc_del_mac_steering_filter(struct igc_adapter *adapter, | ||
| 2403 | const u8 *addr, u8 queue, u8 flags) | ||
| 2404 | { | ||
| 2405 | return igc_del_mac_filter_flags(adapter, addr, queue, | ||
| 2406 | IGC_MAC_STATE_QUEUE_STEERING | flags); | ||
| 2407 | } | ||
| 2408 | |||
| 1970 | /** | 2409 | /** |
| 1971 | * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set | 2410 | * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set |
| 1972 | * @netdev: network interface device structure | 2411 | * @netdev: network interface device structure |
| @@ -3434,6 +3873,9 @@ static const struct net_device_ops igc_netdev_ops = { | |||
| 3434 | .ndo_set_mac_address = igc_set_mac, | 3873 | .ndo_set_mac_address = igc_set_mac, |
| 3435 | .ndo_change_mtu = igc_change_mtu, | 3874 | .ndo_change_mtu = igc_change_mtu, |
| 3436 | .ndo_get_stats = igc_get_stats, | 3875 | .ndo_get_stats = igc_get_stats, |
| 3876 | .ndo_fix_features = igc_fix_features, | ||
| 3877 | .ndo_set_features = igc_set_features, | ||
| 3878 | .ndo_features_check = igc_features_check, | ||
| 3437 | }; | 3879 | }; |
| 3438 | 3880 | ||
| 3439 | /* PCIe configuration access */ | 3881 | /* PCIe configuration access */ |
| @@ -3663,6 +4105,9 @@ static int igc_probe(struct pci_dev *pdev, | |||
| 3663 | if (err) | 4105 | if (err) |
| 3664 | goto err_sw_init; | 4106 | goto err_sw_init; |
| 3665 | 4107 | ||
| 4108 | /* copy netdev features into list of user selectable features */ | ||
| 4109 | netdev->hw_features |= NETIF_F_NTUPLE; | ||
| 4110 | |||
| 3666 | /* MTU range: 68 - 9216 */ | 4111 | /* MTU range: 68 - 9216 */ |
| 3667 | netdev->min_mtu = ETH_MIN_MTU; | 4112 | netdev->min_mtu = ETH_MIN_MTU; |
| 3668 | netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE; | 4113 | netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE; |
diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h index 5afe7a8d3faf..50d7c04dccf5 100644 --- a/drivers/net/ethernet/intel/igc/igc_regs.h +++ b/drivers/net/ethernet/intel/igc/igc_regs.h | |||
| @@ -80,8 +80,23 @@ | |||
| 80 | /* MSI-X Table Register Descriptions */ | 80 | /* MSI-X Table Register Descriptions */ |
| 81 | #define IGC_PBACL 0x05B68 /* MSIx PBA Clear - R/W 1 to clear */ | 81 | #define IGC_PBACL 0x05B68 /* MSIx PBA Clear - R/W 1 to clear */ |
| 82 | 82 | ||
| 83 | /* RSS registers */ | ||
| 84 | #define IGC_MRQC 0x05818 /* Multiple Receive Control - RW */ | ||
| 85 | |||
| 86 | /* Filtering Registers */ | ||
| 87 | #define IGC_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */ | ||
| 88 | |||
| 89 | /* ETQF register bit definitions */ | ||
| 90 | #define IGC_ETQF_FILTER_ENABLE BIT(26) | ||
| 91 | #define IGC_ETQF_QUEUE_ENABLE BIT(31) | ||
| 92 | #define IGC_ETQF_QUEUE_SHIFT 16 | ||
| 93 | #define IGC_ETQF_QUEUE_MASK 0x00070000 | ||
| 94 | #define IGC_ETQF_ETYPE_MASK 0x0000FFFF | ||
| 95 | |||
| 83 | /* Redirection Table - RW Array */ | 96 | /* Redirection Table - RW Array */ |
| 84 | #define IGC_RETA(_i) (0x05C00 + ((_i) * 4)) | 97 | #define IGC_RETA(_i) (0x05C00 + ((_i) * 4)) |
| 98 | /* RSS Random Key - RW Array */ | ||
| 99 | #define IGC_RSSRK(_i) (0x05C80 + ((_i) * 4)) | ||
| 85 | 100 | ||
| 86 | /* Receive Register Descriptions */ | 101 | /* Receive Register Descriptions */ |
| 87 | #define IGC_RCTL 0x00100 /* Rx Control - RW */ | 102 | #define IGC_RCTL 0x00100 /* Rx Control - RW */ |
| @@ -101,6 +116,7 @@ | |||
| 101 | #define IGC_UTA 0x0A000 /* Unicast Table Array - RW */ | 116 | #define IGC_UTA 0x0A000 /* Unicast Table Array - RW */ |
| 102 | #define IGC_RAL(_n) (0x05400 + ((_n) * 0x08)) | 117 | #define IGC_RAL(_n) (0x05400 + ((_n) * 0x08)) |
| 103 | #define IGC_RAH(_n) (0x05404 + ((_n) * 0x08)) | 118 | #define IGC_RAH(_n) (0x05404 + ((_n) * 0x08)) |
| 119 | #define IGC_VLAPQF 0x055B0 /* VLAN Priority Queue Filter VLAPQF */ | ||
| 104 | 120 | ||
| 105 | /* Transmit Register Descriptions */ | 121 | /* Transmit Register Descriptions */ |
| 106 | #define IGC_TCTL 0x00400 /* Tx Control - RW */ | 122 | #define IGC_TCTL 0x00400 /* Tx Control - RW */ |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index e100054a3765..76aeed845a73 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
| @@ -9796,7 +9796,7 @@ static int ixgbe_set_features(struct net_device *netdev, | |||
| 9796 | NETIF_F_HW_VLAN_CTAG_FILTER)) | 9796 | NETIF_F_HW_VLAN_CTAG_FILTER)) |
| 9797 | ixgbe_set_rx_mode(netdev); | 9797 | ixgbe_set_rx_mode(netdev); |
| 9798 | 9798 | ||
| 9799 | return 0; | 9799 | return 1; |
| 9800 | } | 9800 | } |
| 9801 | 9801 | ||
| 9802 | /** | 9802 | /** |
