Skip to content

Commit e9350d4

Browse files
committed
Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== 1GbE Intel Wired LAN Driver Updates 2018-04-25 This series enables some ethtool and tc-flower filters to be offloaded to igb-based network controllers. This is useful when the system configuration wants to steer kinds of traffic to a specific hardware queue for i210 devices only. The first two patch in the series are bug fixes. The basis of this series is to export the internal API used to configure address filters, so they can be used by ethtool, and extending the functionality so an source address can be handled. Then, we enable the tc-flower offloading implementation to re-use the same infrastructure as ethtool, and storing them in the per-adapter "nfc" (Network Filter Config?) list. But for consistency, for destructive access they are separated, i.e. an filter added by tc-flower can only be removed by tc-flower, but ethtool can read them all. Only support for VLAN Prio, Source and Destination MAC Address, and Ethertype is enabled for now. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents c8ad089 + e086be9 commit e9350d4

File tree

4 files changed

+439
-15
lines changed

4 files changed

+439
-15
lines changed

drivers/net/ethernet/intel/igb/e1000_defines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,8 @@
491491
* manageability enabled, allowing us room for 15 multicast addresses.
492492
*/
493493
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
494+
#define E1000_RAH_ASEL_SRC_ADDR 0x00010000
495+
#define E1000_RAH_QSEL_ENABLE 0x10000000
494496
#define E1000_RAL_MAC_ADDR_LEN 4
495497
#define E1000_RAH_MAC_ADDR_LEN 2
496498
#define E1000_RAH_POOL_MASK 0x03FC0000

drivers/net/ethernet/intel/igb/igb.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,8 @@ struct hwmon_buff {
442442
enum igb_filter_match_flags {
443443
IGB_FILTER_FLAG_ETHER_TYPE = 0x1,
444444
IGB_FILTER_FLAG_VLAN_TCI = 0x2,
445+
IGB_FILTER_FLAG_SRC_MAC_ADDR = 0x4,
446+
IGB_FILTER_FLAG_DST_MAC_ADDR = 0x8,
445447
};
446448

447449
#define IGB_MAX_RXNFC_FILTERS 16
@@ -456,11 +458,14 @@ struct igb_nfc_input {
456458
u8 match_flags;
457459
__be16 etype;
458460
__be16 vlan_tci;
461+
u8 src_addr[ETH_ALEN];
462+
u8 dst_addr[ETH_ALEN];
459463
};
460464

461465
struct igb_nfc_filter {
462466
struct hlist_node nfc_node;
463467
struct igb_nfc_input filter;
468+
unsigned long cookie;
464469
u16 etype_reg_index;
465470
u16 sw_idx;
466471
u16 action;
@@ -474,6 +479,8 @@ struct igb_mac_addr {
474479

475480
#define IGB_MAC_STATE_DEFAULT 0x1
476481
#define IGB_MAC_STATE_IN_USE 0x2
482+
#define IGB_MAC_STATE_SRC_ADDR 0x4
483+
#define IGB_MAC_STATE_QUEUE_STEERING 0x8
477484

478485
/* board specific private data structure */
479486
struct igb_adapter {
@@ -598,6 +605,7 @@ struct igb_adapter {
598605

599606
/* RX network flow classification support */
600607
struct hlist_head nfc_filter_list;
608+
struct hlist_head cls_flower_list;
601609
unsigned int nfc_filter_count;
602610
/* lock for RX network flow classification filter */
603611
spinlock_t nfc_lock;
@@ -739,4 +747,9 @@ int igb_add_filter(struct igb_adapter *adapter,
739747
int igb_erase_filter(struct igb_adapter *adapter,
740748
struct igb_nfc_filter *input);
741749

750+
int igb_add_mac_steering_filter(struct igb_adapter *adapter,
751+
const u8 *addr, u8 queue, u8 flags);
752+
int igb_del_mac_steering_filter(struct igb_adapter *adapter,
753+
const u8 *addr, u8 queue, u8 flags);
754+
742755
#endif /* _IGB_H_ */

drivers/net/ethernet/intel/igb/igb_ethtool.c

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,6 +2495,23 @@ static int igb_get_ethtool_nfc_entry(struct igb_adapter *adapter,
24952495
fsp->h_ext.vlan_tci = rule->filter.vlan_tci;
24962496
fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK);
24972497
}
2498+
if (rule->filter.match_flags & IGB_FILTER_FLAG_DST_MAC_ADDR) {
2499+
ether_addr_copy(fsp->h_u.ether_spec.h_dest,
2500+
rule->filter.dst_addr);
2501+
/* As we only support matching by the full
2502+
* mask, return the mask to userspace
2503+
*/
2504+
eth_broadcast_addr(fsp->m_u.ether_spec.h_dest);
2505+
}
2506+
if (rule->filter.match_flags & IGB_FILTER_FLAG_SRC_MAC_ADDR) {
2507+
ether_addr_copy(fsp->h_u.ether_spec.h_source,
2508+
rule->filter.src_addr);
2509+
/* As we only support matching by the full
2510+
* mask, return the mask to userspace
2511+
*/
2512+
eth_broadcast_addr(fsp->m_u.ether_spec.h_source);
2513+
}
2514+
24982515
return 0;
24992516
}
25002517
return -EINVAL;
@@ -2768,14 +2785,41 @@ static int igb_rxnfc_write_vlan_prio_filter(struct igb_adapter *adapter,
27682785

27692786
int igb_add_filter(struct igb_adapter *adapter, struct igb_nfc_filter *input)
27702787
{
2788+
struct e1000_hw *hw = &adapter->hw;
27712789
int err = -EINVAL;
27722790

2791+
if (hw->mac.type == e1000_i210 &&
2792+
!(input->filter.match_flags & ~IGB_FILTER_FLAG_SRC_MAC_ADDR)) {
2793+
dev_err(&adapter->pdev->dev,
2794+
"i210 doesn't support flow classification rules specifying only source addresses.\n");
2795+
return -EOPNOTSUPP;
2796+
}
2797+
27732798
if (input->filter.match_flags & IGB_FILTER_FLAG_ETHER_TYPE) {
27742799
err = igb_rxnfc_write_etype_filter(adapter, input);
27752800
if (err)
27762801
return err;
27772802
}
27782803

2804+
if (input->filter.match_flags & IGB_FILTER_FLAG_DST_MAC_ADDR) {
2805+
err = igb_add_mac_steering_filter(adapter,
2806+
input->filter.dst_addr,
2807+
input->action, 0);
2808+
err = min_t(int, err, 0);
2809+
if (err)
2810+
return err;
2811+
}
2812+
2813+
if (input->filter.match_flags & IGB_FILTER_FLAG_SRC_MAC_ADDR) {
2814+
err = igb_add_mac_steering_filter(adapter,
2815+
input->filter.src_addr,
2816+
input->action,
2817+
IGB_MAC_STATE_SRC_ADDR);
2818+
err = min_t(int, err, 0);
2819+
if (err)
2820+
return err;
2821+
}
2822+
27792823
if (input->filter.match_flags & IGB_FILTER_FLAG_VLAN_TCI)
27802824
err = igb_rxnfc_write_vlan_prio_filter(adapter, input);
27812825

@@ -2824,6 +2868,15 @@ int igb_erase_filter(struct igb_adapter *adapter, struct igb_nfc_filter *input)
28242868
igb_clear_vlan_prio_filter(adapter,
28252869
ntohs(input->filter.vlan_tci));
28262870

2871+
if (input->filter.match_flags & IGB_FILTER_FLAG_SRC_MAC_ADDR)
2872+
igb_del_mac_steering_filter(adapter, input->filter.src_addr,
2873+
input->action,
2874+
IGB_MAC_STATE_SRC_ADDR);
2875+
2876+
if (input->filter.match_flags & IGB_FILTER_FLAG_DST_MAC_ADDR)
2877+
igb_del_mac_steering_filter(adapter, input->filter.dst_addr,
2878+
input->action, 0);
2879+
28272880
return 0;
28282881
}
28292882

@@ -2865,7 +2918,7 @@ static int igb_update_ethtool_nfc_entry(struct igb_adapter *adapter,
28652918

28662919
/* add filter to the list */
28672920
if (parent)
2868-
hlist_add_behind(&parent->nfc_node, &input->nfc_node);
2921+
hlist_add_behind(&input->nfc_node, &parent->nfc_node);
28692922
else
28702923
hlist_add_head(&input->nfc_node, &adapter->nfc_filter_list);
28712924

@@ -2905,10 +2958,6 @@ static int igb_add_ethtool_nfc_entry(struct igb_adapter *adapter,
29052958
if ((fsp->flow_type & ~FLOW_EXT) != ETHER_FLOW)
29062959
return -EINVAL;
29072960

2908-
if (fsp->m_u.ether_spec.h_proto != ETHER_TYPE_FULL_MASK &&
2909-
fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK))
2910-
return -EINVAL;
2911-
29122961
input = kzalloc(sizeof(*input), GFP_KERNEL);
29132962
if (!input)
29142963
return -ENOMEM;
@@ -2918,6 +2967,20 @@ static int igb_add_ethtool_nfc_entry(struct igb_adapter *adapter,
29182967
input->filter.match_flags = IGB_FILTER_FLAG_ETHER_TYPE;
29192968
}
29202969

2970+
/* Only support matching addresses by the full mask */
2971+
if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_source)) {
2972+
input->filter.match_flags |= IGB_FILTER_FLAG_SRC_MAC_ADDR;
2973+
ether_addr_copy(input->filter.src_addr,
2974+
fsp->h_u.ether_spec.h_source);
2975+
}
2976+
2977+
/* Only support matching addresses by the full mask */
2978+
if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_dest)) {
2979+
input->filter.match_flags |= IGB_FILTER_FLAG_DST_MAC_ADDR;
2980+
ether_addr_copy(input->filter.dst_addr,
2981+
fsp->h_u.ether_spec.h_dest);
2982+
}
2983+
29212984
if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) {
29222985
if (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) {
29232986
err = -EINVAL;

0 commit comments

Comments
 (0)