aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSasha Neftin <sasha.neftin@intel.com>2019-02-14 06:31:37 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2019-03-19 17:45:23 -0400
commit6245c8483ae0110d2eb7e7cd2922dba1a5fce720 (patch)
tree0780b1b6fdfe6a01d5722bee77e039b83bf93c9a
parent2121c2712f8249e4d2555a4c989e4666aba34031 (diff)
igc: Extend the ethtool supporting
Add show and configure network flow classification (NFC) methods to the ethtool. Show the specifies Rx ntuple filters. Configures receive network flow classification option or rules. Signed-off-by: Sasha Neftin <sasha.neftin@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/igc/igc.h55
-rw-r--r--drivers/net/ethernet/intel/igc/igc_defines.h4
-rw-r--r--drivers/net/ethernet/intel/igc/igc_ethtool.c602
-rw-r--r--drivers/net/ethernet/intel/igc/igc_main.c145
-rw-r--r--drivers/net/ethernet/intel/igc/igc_regs.h11
5 files changed, 814 insertions, 3 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 473a65c51382..7eee12972d86 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -33,6 +33,10 @@ void igc_write_rss_indir_tbl(struct igc_adapter *adapter);
33bool igc_has_link(struct igc_adapter *adapter); 33bool igc_has_link(struct igc_adapter *adapter);
34void igc_reset(struct igc_adapter *adapter); 34void igc_reset(struct igc_adapter *adapter);
35int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx); 35int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx);
36int igc_add_mac_steering_filter(struct igc_adapter *adapter,
37 const u8 *addr, u8 queue, u8 flags);
38int igc_del_mac_steering_filter(struct igc_adapter *adapter,
39 const u8 *addr, u8 queue, u8 flags);
36 40
37extern char igc_driver_name[]; 41extern char igc_driver_name[];
38extern char igc_driver_version[]; 42extern char igc_driver_version[];
@@ -292,15 +296,50 @@ struct igc_q_vector {
292 struct igc_ring ring[0] ____cacheline_internodealigned_in_smp; 296 struct igc_ring ring[0] ____cacheline_internodealigned_in_smp;
293}; 297};
294 298
299#define MAX_ETYPE_FILTER (4 - 1)
300
301enum igc_filter_match_flags {
302 IGC_FILTER_FLAG_ETHER_TYPE = 0x1,
303 IGC_FILTER_FLAG_VLAN_TCI = 0x2,
304 IGC_FILTER_FLAG_SRC_MAC_ADDR = 0x4,
305 IGC_FILTER_FLAG_DST_MAC_ADDR = 0x8,
306};
307
308/* RX network flow classification data structure */
309struct igc_nfc_input {
310 /* Byte layout in order, all values with MSB first:
311 * match_flags - 1 byte
312 * etype - 2 bytes
313 * vlan_tci - 2 bytes
314 */
315 u8 match_flags;
316 __be16 etype;
317 __be16 vlan_tci;
318 u8 src_addr[ETH_ALEN];
319 u8 dst_addr[ETH_ALEN];
320};
321
322struct igc_nfc_filter {
323 struct hlist_node nfc_node;
324 struct igc_nfc_input filter;
325 unsigned long cookie;
326 u16 etype_reg_index;
327 u16 sw_idx;
328 u16 action;
329};
330
295struct igc_mac_addr { 331struct igc_mac_addr {
296 u8 addr[ETH_ALEN]; 332 u8 addr[ETH_ALEN];
297 u8 queue; 333 u8 queue;
298 u8 state; /* bitmask */ 334 u8 state; /* bitmask */
299}; 335};
300 336
301#define IGC_MAC_STATE_DEFAULT 0x1 337#define IGC_MAC_STATE_DEFAULT 0x1
302#define IGC_MAC_STATE_MODIFIED 0x2 338#define IGC_MAC_STATE_IN_USE 0x2
303#define IGC_MAC_STATE_IN_USE 0x4 339#define IGC_MAC_STATE_SRC_ADDR 0x4
340#define IGC_MAC_STATE_QUEUE_STEERING 0x8
341
342#define IGC_MAX_RXNFC_FILTERS 16
304 343
305/* Board specific private data structure */ 344/* Board specific private data structure */
306struct igc_adapter { 345struct igc_adapter {
@@ -369,8 +408,14 @@ struct igc_adapter {
369 u32 rss_queues; 408 u32 rss_queues;
370 u32 rss_indir_tbl_init; 409 u32 rss_indir_tbl_init;
371 410
411 /* RX network flow classification support */
412 struct hlist_head nfc_filter_list;
413 struct hlist_head cls_flower_list;
414 unsigned int nfc_filter_count;
415
372 /* lock for RX network flow classification filter */ 416 /* lock for RX network flow classification filter */
373 spinlock_t nfc_lock; 417 spinlock_t nfc_lock;
418 bool etype_bitmap[MAX_ETYPE_FILTER];
374 419
375 struct igc_mac_addr *mac_table; 420 struct igc_mac_addr *mac_table;
376 421
@@ -456,6 +501,10 @@ static inline s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data)
456 501
457/* forward declaration */ 502/* forward declaration */
458void igc_reinit_locked(struct igc_adapter *); 503void igc_reinit_locked(struct igc_adapter *);
504int igc_add_filter(struct igc_adapter *adapter,
505 struct igc_nfc_filter *input);
506int igc_erase_filter(struct igc_adapter *adapter,
507 struct igc_nfc_filter *input);
459 508
460#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring)) 509#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))
461 510
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index 3666f8837cc8..925c89b57ec5 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -400,4 +400,8 @@
400 400
401#define IGC_N0_QUEUE -1 401#define IGC_N0_QUEUE -1
402 402
403#define IGC_VLAPQF_QUEUE_SEL(_n, q_idx) ((q_idx) << ((_n) * 4))
404#define IGC_VLAPQF_P_VALID(_n) (0x1 << (3 + (_n) * 4))
405#define IGC_VLAPQF_QUEUE_MASK 0x03
406
403#endif /* _IGC_DEFINES_H_ */ 407#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..25d14fc82bf8 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -2,6 +2,7 @@
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"
@@ -643,6 +644,605 @@ static int igc_set_coalesce(struct net_device *netdev,
643 return 0; 644 return 0;
644} 645}
645 646
647#define ETHER_TYPE_FULL_MASK ((__force __be16)~0)
648static int igc_get_ethtool_nfc_entry(struct igc_adapter *adapter,
649 struct ethtool_rxnfc *cmd)
650{
651 struct ethtool_rx_flow_spec *fsp = &cmd->fs;
652 struct igc_nfc_filter *rule = NULL;
653
654 /* report total rule count */
655 cmd->data = IGC_MAX_RXNFC_FILTERS;
656
657 hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) {
658 if (fsp->location <= rule->sw_idx)
659 break;
660 }
661
662 if (!rule || fsp->location != rule->sw_idx)
663 return -EINVAL;
664
665 if (rule->filter.match_flags) {
666 fsp->flow_type = ETHER_FLOW;
667 fsp->ring_cookie = rule->action;
668 if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
669 fsp->h_u.ether_spec.h_proto = rule->filter.etype;
670 fsp->m_u.ether_spec.h_proto = ETHER_TYPE_FULL_MASK;
671 }
672 if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
673 fsp->flow_type |= FLOW_EXT;
674 fsp->h_ext.vlan_tci = rule->filter.vlan_tci;
675 fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK);
676 }
677 if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
678 ether_addr_copy(fsp->h_u.ether_spec.h_dest,
679 rule->filter.dst_addr);
680 /* As we only support matching by the full
681 * mask, return the mask to userspace
682 */
683 eth_broadcast_addr(fsp->m_u.ether_spec.h_dest);
684 }
685 if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
686 ether_addr_copy(fsp->h_u.ether_spec.h_source,
687 rule->filter.src_addr);
688 /* As we only support matching by the full
689 * mask, return the mask to userspace
690 */
691 eth_broadcast_addr(fsp->m_u.ether_spec.h_source);
692 }
693
694 return 0;
695 }
696 return -EINVAL;
697}
698
699static int igc_get_ethtool_nfc_all(struct igc_adapter *adapter,
700 struct ethtool_rxnfc *cmd,
701 u32 *rule_locs)
702{
703 struct igc_nfc_filter *rule;
704 int cnt = 0;
705
706 /* report total rule count */
707 cmd->data = IGC_MAX_RXNFC_FILTERS;
708
709 hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) {
710 if (cnt == cmd->rule_cnt)
711 return -EMSGSIZE;
712 rule_locs[cnt] = rule->sw_idx;
713 cnt++;
714 }
715
716 cmd->rule_cnt = cnt;
717
718 return 0;
719}
720
721static int igc_get_rss_hash_opts(struct igc_adapter *adapter,
722 struct ethtool_rxnfc *cmd)
723{
724 cmd->data = 0;
725
726 /* Report default options for RSS on igc */
727 switch (cmd->flow_type) {
728 case TCP_V4_FLOW:
729 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
730 /* Fall through */
731 case UDP_V4_FLOW:
732 if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV4_UDP)
733 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
734 /* Fall through */
735 case SCTP_V4_FLOW:
736 /* Fall through */
737 case AH_ESP_V4_FLOW:
738 /* Fall through */
739 case AH_V4_FLOW:
740 /* Fall through */
741 case ESP_V4_FLOW:
742 /* Fall through */
743 case IPV4_FLOW:
744 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
745 break;
746 case TCP_V6_FLOW:
747 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
748 /* Fall through */
749 case UDP_V6_FLOW:
750 if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV6_UDP)
751 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
752 /* Fall through */
753 case SCTP_V6_FLOW:
754 /* Fall through */
755 case AH_ESP_V6_FLOW:
756 /* Fall through */
757 case AH_V6_FLOW:
758 /* Fall through */
759 case ESP_V6_FLOW:
760 /* Fall through */
761 case IPV6_FLOW:
762 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
763 break;
764 default:
765 return -EINVAL;
766 }
767
768 return 0;
769}
770
771static int igc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
772 u32 *rule_locs)
773{
774 struct igc_adapter *adapter = netdev_priv(dev);
775 int ret = -EOPNOTSUPP;
776
777 switch (cmd->cmd) {
778 case ETHTOOL_GRXRINGS:
779 cmd->data = adapter->num_rx_queues;
780 ret = 0;
781 break;
782 case ETHTOOL_GRXCLSRLCNT:
783 cmd->rule_cnt = adapter->nfc_filter_count;
784 ret = 0;
785 break;
786 case ETHTOOL_GRXCLSRULE:
787 ret = igc_get_ethtool_nfc_entry(adapter, cmd);
788 break;
789 case ETHTOOL_GRXCLSRLALL:
790 ret = igc_get_ethtool_nfc_all(adapter, cmd, rule_locs);
791 break;
792 case ETHTOOL_GRXFH:
793 ret = igc_get_rss_hash_opts(adapter, cmd);
794 break;
795 default:
796 break;
797 }
798
799 return ret;
800}
801
802#define UDP_RSS_FLAGS (IGC_FLAG_RSS_FIELD_IPV4_UDP | \
803 IGC_FLAG_RSS_FIELD_IPV6_UDP)
804static int igc_set_rss_hash_opt(struct igc_adapter *adapter,
805 struct ethtool_rxnfc *nfc)
806{
807 u32 flags = adapter->flags;
808
809 /* RSS does not support anything other than hashing
810 * to queues on src and dst IPs and ports
811 */
812 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
813 RXH_L4_B_0_1 | RXH_L4_B_2_3))
814 return -EINVAL;
815
816 switch (nfc->flow_type) {
817 case TCP_V4_FLOW:
818 case TCP_V6_FLOW:
819 if (!(nfc->data & RXH_IP_SRC) ||
820 !(nfc->data & RXH_IP_DST) ||
821 !(nfc->data & RXH_L4_B_0_1) ||
822 !(nfc->data & RXH_L4_B_2_3))
823 return -EINVAL;
824 break;
825 case UDP_V4_FLOW:
826 if (!(nfc->data & RXH_IP_SRC) ||
827 !(nfc->data & RXH_IP_DST))
828 return -EINVAL;
829 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
830 case 0:
831 flags &= ~IGC_FLAG_RSS_FIELD_IPV4_UDP;
832 break;
833 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
834 flags |= IGC_FLAG_RSS_FIELD_IPV4_UDP;
835 break;
836 default:
837 return -EINVAL;
838 }
839 break;
840 case UDP_V6_FLOW:
841 if (!(nfc->data & RXH_IP_SRC) ||
842 !(nfc->data & RXH_IP_DST))
843 return -EINVAL;
844 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
845 case 0:
846 flags &= ~IGC_FLAG_RSS_FIELD_IPV6_UDP;
847 break;
848 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
849 flags |= IGC_FLAG_RSS_FIELD_IPV6_UDP;
850 break;
851 default:
852 return -EINVAL;
853 }
854 break;
855 case AH_ESP_V4_FLOW:
856 case AH_V4_FLOW:
857 case ESP_V4_FLOW:
858 case SCTP_V4_FLOW:
859 case AH_ESP_V6_FLOW:
860 case AH_V6_FLOW:
861 case ESP_V6_FLOW:
862 case SCTP_V6_FLOW:
863 if (!(nfc->data & RXH_IP_SRC) ||
864 !(nfc->data & RXH_IP_DST) ||
865 (nfc->data & RXH_L4_B_0_1) ||
866 (nfc->data & RXH_L4_B_2_3))
867 return -EINVAL;
868 break;
869 default:
870 return -EINVAL;
871 }
872
873 /* if we changed something we need to update flags */
874 if (flags != adapter->flags) {
875 struct igc_hw *hw = &adapter->hw;
876 u32 mrqc = rd32(IGC_MRQC);
877
878 if ((flags & UDP_RSS_FLAGS) &&
879 !(adapter->flags & UDP_RSS_FLAGS))
880 dev_err(&adapter->pdev->dev,
881 "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n");
882
883 adapter->flags = flags;
884
885 /* Perform hash on these packet types */
886 mrqc |= IGC_MRQC_RSS_FIELD_IPV4 |
887 IGC_MRQC_RSS_FIELD_IPV4_TCP |
888 IGC_MRQC_RSS_FIELD_IPV6 |
889 IGC_MRQC_RSS_FIELD_IPV6_TCP;
890
891 mrqc &= ~(IGC_MRQC_RSS_FIELD_IPV4_UDP |
892 IGC_MRQC_RSS_FIELD_IPV6_UDP);
893
894 if (flags & IGC_FLAG_RSS_FIELD_IPV4_UDP)
895 mrqc |= IGC_MRQC_RSS_FIELD_IPV4_UDP;
896
897 if (flags & IGC_FLAG_RSS_FIELD_IPV6_UDP)
898 mrqc |= IGC_MRQC_RSS_FIELD_IPV6_UDP;
899
900 wr32(IGC_MRQC, mrqc);
901 }
902
903 return 0;
904}
905
906static int igc_rxnfc_write_etype_filter(struct igc_adapter *adapter,
907 struct igc_nfc_filter *input)
908{
909 struct igc_hw *hw = &adapter->hw;
910 u8 i;
911 u32 etqf;
912 u16 etype;
913
914 /* find an empty etype filter register */
915 for (i = 0; i < MAX_ETYPE_FILTER; ++i) {
916 if (!adapter->etype_bitmap[i])
917 break;
918 }
919 if (i == MAX_ETYPE_FILTER) {
920 dev_err(&adapter->pdev->dev, "ethtool -N: etype filters are all used.\n");
921 return -EINVAL;
922 }
923
924 adapter->etype_bitmap[i] = true;
925
926 etqf = rd32(IGC_ETQF(i));
927 etype = ntohs(input->filter.etype & ETHER_TYPE_FULL_MASK);
928
929 etqf |= IGC_ETQF_FILTER_ENABLE;
930 etqf &= ~IGC_ETQF_ETYPE_MASK;
931 etqf |= (etype & IGC_ETQF_ETYPE_MASK);
932
933 etqf &= ~IGC_ETQF_QUEUE_MASK;
934 etqf |= ((input->action << IGC_ETQF_QUEUE_SHIFT)
935 & IGC_ETQF_QUEUE_MASK);
936 etqf |= IGC_ETQF_QUEUE_ENABLE;
937
938 wr32(IGC_ETQF(i), etqf);
939
940 input->etype_reg_index = i;
941
942 return 0;
943}
944
945static int igc_rxnfc_write_vlan_prio_filter(struct igc_adapter *adapter,
946 struct igc_nfc_filter *input)
947{
948 struct igc_hw *hw = &adapter->hw;
949 u8 vlan_priority;
950 u16 queue_index;
951 u32 vlapqf;
952
953 vlapqf = rd32(IGC_VLAPQF);
954 vlan_priority = (ntohs(input->filter.vlan_tci) & VLAN_PRIO_MASK)
955 >> VLAN_PRIO_SHIFT;
956 queue_index = (vlapqf >> (vlan_priority * 4)) & IGC_VLAPQF_QUEUE_MASK;
957
958 /* check whether this vlan prio is already set */
959 if (vlapqf & IGC_VLAPQF_P_VALID(vlan_priority) &&
960 queue_index != input->action) {
961 dev_err(&adapter->pdev->dev, "ethtool rxnfc set vlan prio filter failed.\n");
962 return -EEXIST;
963 }
964
965 vlapqf |= IGC_VLAPQF_P_VALID(vlan_priority);
966 vlapqf |= IGC_VLAPQF_QUEUE_SEL(vlan_priority, input->action);
967
968 wr32(IGC_VLAPQF, vlapqf);
969
970 return 0;
971}
972
973int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
974{
975 struct igc_hw *hw = &adapter->hw;
976 int err = -EINVAL;
977
978 if (hw->mac.type == igc_i225 &&
979 !(input->filter.match_flags & ~IGC_FILTER_FLAG_SRC_MAC_ADDR)) {
980 dev_err(&adapter->pdev->dev,
981 "i225 doesn't support flow classification rules specifying only source addresses.\n");
982 return -EOPNOTSUPP;
983 }
984
985 if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
986 err = igc_rxnfc_write_etype_filter(adapter, input);
987 if (err)
988 return err;
989 }
990
991 if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
992 err = igc_add_mac_steering_filter(adapter,
993 input->filter.dst_addr,
994 input->action, 0);
995 err = min_t(int, err, 0);
996 if (err)
997 return err;
998 }
999
1000 if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
1001 err = igc_add_mac_steering_filter(adapter,
1002 input->filter.src_addr,
1003 input->action,
1004 IGC_MAC_STATE_SRC_ADDR);
1005 err = min_t(int, err, 0);
1006 if (err)
1007 return err;
1008 }
1009
1010 if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI)
1011 err = igc_rxnfc_write_vlan_prio_filter(adapter, input);
1012
1013 return err;
1014}
1015
1016static void igc_clear_etype_filter_regs(struct igc_adapter *adapter,
1017 u16 reg_index)
1018{
1019 struct igc_hw *hw = &adapter->hw;
1020 u32 etqf = rd32(IGC_ETQF(reg_index));
1021
1022 etqf &= ~IGC_ETQF_QUEUE_ENABLE;
1023 etqf &= ~IGC_ETQF_QUEUE_MASK;
1024 etqf &= ~IGC_ETQF_FILTER_ENABLE;
1025
1026 wr32(IGC_ETQF(reg_index), etqf);
1027
1028 adapter->etype_bitmap[reg_index] = false;
1029}
1030
1031static void igc_clear_vlan_prio_filter(struct igc_adapter *adapter,
1032 u16 vlan_tci)
1033{
1034 struct igc_hw *hw = &adapter->hw;
1035 u8 vlan_priority;
1036 u32 vlapqf;
1037
1038 vlan_priority = (vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
1039
1040 vlapqf = rd32(IGC_VLAPQF);
1041 vlapqf &= ~IGC_VLAPQF_P_VALID(vlan_priority);
1042 vlapqf &= ~IGC_VLAPQF_QUEUE_SEL(vlan_priority,
1043 IGC_VLAPQF_QUEUE_MASK);
1044
1045 wr32(IGC_VLAPQF, vlapqf);
1046}
1047
1048int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
1049{
1050 if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE)
1051 igc_clear_etype_filter_regs(adapter,
1052 input->etype_reg_index);
1053
1054 if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI)
1055 igc_clear_vlan_prio_filter(adapter,
1056 ntohs(input->filter.vlan_tci));
1057
1058 if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)
1059 igc_del_mac_steering_filter(adapter, input->filter.src_addr,
1060 input->action,
1061 IGC_MAC_STATE_SRC_ADDR);
1062
1063 if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
1064 igc_del_mac_steering_filter(adapter, input->filter.dst_addr,
1065 input->action, 0);
1066
1067 return 0;
1068}
1069
1070static int igc_update_ethtool_nfc_entry(struct igc_adapter *adapter,
1071 struct igc_nfc_filter *input,
1072 u16 sw_idx)
1073{
1074 struct igc_nfc_filter *rule, *parent;
1075 int err = -EINVAL;
1076
1077 parent = NULL;
1078 rule = NULL;
1079
1080 hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) {
1081 /* hash found, or no matching entry */
1082 if (rule->sw_idx >= sw_idx)
1083 break;
1084 parent = rule;
1085 }
1086
1087 /* if there is an old rule occupying our place remove it */
1088 if (rule && rule->sw_idx == sw_idx) {
1089 if (!input)
1090 err = igc_erase_filter(adapter, rule);
1091
1092 hlist_del(&rule->nfc_node);
1093 kfree(rule);
1094 adapter->nfc_filter_count--;
1095 }
1096
1097 /* If no input this was a delete, err should be 0 if a rule was
1098 * successfully found and removed from the list else -EINVAL
1099 */
1100 if (!input)
1101 return err;
1102
1103 /* initialize node */
1104 INIT_HLIST_NODE(&input->nfc_node);
1105
1106 /* add filter to the list */
1107 if (parent)
1108 hlist_add_behind(&input->nfc_node, &parent->nfc_node);
1109 else
1110 hlist_add_head(&input->nfc_node, &adapter->nfc_filter_list);
1111
1112 /* update counts */
1113 adapter->nfc_filter_count++;
1114
1115 return 0;
1116}
1117
1118static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter,
1119 struct ethtool_rxnfc *cmd)
1120{
1121 struct net_device *netdev = adapter->netdev;
1122 struct ethtool_rx_flow_spec *fsp =
1123 (struct ethtool_rx_flow_spec *)&cmd->fs;
1124 struct igc_nfc_filter *input, *rule;
1125 int err = 0;
1126
1127 if (!(netdev->hw_features & NETIF_F_NTUPLE))
1128 return -EOPNOTSUPP;
1129
1130 /* Don't allow programming if the action is a queue greater than
1131 * the number of online Rx queues.
1132 */
1133 if (fsp->ring_cookie == RX_CLS_FLOW_DISC ||
1134 fsp->ring_cookie >= adapter->num_rx_queues) {
1135 dev_err(&adapter->pdev->dev, "ethtool -N: The specified action is invalid\n");
1136 return -EINVAL;
1137 }
1138
1139 /* Don't allow indexes to exist outside of available space */
1140 if (fsp->location >= IGC_MAX_RXNFC_FILTERS) {
1141 dev_err(&adapter->pdev->dev, "Location out of range\n");
1142 return -EINVAL;
1143 }
1144
1145 if ((fsp->flow_type & ~FLOW_EXT) != ETHER_FLOW)
1146 return -EINVAL;
1147
1148 input = kzalloc(sizeof(*input), GFP_KERNEL);
1149 if (!input)
1150 return -ENOMEM;
1151
1152 if (fsp->m_u.ether_spec.h_proto == ETHER_TYPE_FULL_MASK) {
1153 input->filter.etype = fsp->h_u.ether_spec.h_proto;
1154 input->filter.match_flags = IGC_FILTER_FLAG_ETHER_TYPE;
1155 }
1156
1157 /* Only support matching addresses by the full mask */
1158 if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_source)) {
1159 input->filter.match_flags |= IGC_FILTER_FLAG_SRC_MAC_ADDR;
1160 ether_addr_copy(input->filter.src_addr,
1161 fsp->h_u.ether_spec.h_source);
1162 }
1163
1164 /* Only support matching addresses by the full mask */
1165 if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_dest)) {
1166 input->filter.match_flags |= IGC_FILTER_FLAG_DST_MAC_ADDR;
1167 ether_addr_copy(input->filter.dst_addr,
1168 fsp->h_u.ether_spec.h_dest);
1169 }
1170
1171 if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) {
1172 if (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) {
1173 err = -EINVAL;
1174 goto err_out;
1175 }
1176 input->filter.vlan_tci = fsp->h_ext.vlan_tci;
1177 input->filter.match_flags |= IGC_FILTER_FLAG_VLAN_TCI;
1178 }
1179
1180 input->action = fsp->ring_cookie;
1181 input->sw_idx = fsp->location;
1182
1183 spin_lock(&adapter->nfc_lock);
1184
1185 hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) {
1186 if (!memcmp(&input->filter, &rule->filter,
1187 sizeof(input->filter))) {
1188 err = -EEXIST;
1189 dev_err(&adapter->pdev->dev,
1190 "ethtool: this filter is already set\n");
1191 goto err_out_w_lock;
1192 }
1193 }
1194
1195 err = igc_add_filter(adapter, input);
1196 if (err)
1197 goto err_out_w_lock;
1198
1199 igc_update_ethtool_nfc_entry(adapter, input, input->sw_idx);
1200
1201 spin_unlock(&adapter->nfc_lock);
1202 return 0;
1203
1204err_out_w_lock:
1205 spin_unlock(&adapter->nfc_lock);
1206err_out:
1207 kfree(input);
1208 return err;
1209}
1210
1211static int igc_del_ethtool_nfc_entry(struct igc_adapter *adapter,
1212 struct ethtool_rxnfc *cmd)
1213{
1214 struct ethtool_rx_flow_spec *fsp =
1215 (struct ethtool_rx_flow_spec *)&cmd->fs;
1216 int err;
1217
1218 spin_lock(&adapter->nfc_lock);
1219 err = igc_update_ethtool_nfc_entry(adapter, NULL, fsp->location);
1220 spin_unlock(&adapter->nfc_lock);
1221
1222 return err;
1223}
1224
1225static int igc_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
1226{
1227 struct igc_adapter *adapter = netdev_priv(dev);
1228 int ret = -EOPNOTSUPP;
1229
1230 switch (cmd->cmd) {
1231 case ETHTOOL_SRXFH:
1232 ret = igc_set_rss_hash_opt(adapter, cmd);
1233 break;
1234 case ETHTOOL_SRXCLSRLINS:
1235 ret = igc_add_ethtool_nfc_entry(adapter, cmd);
1236 break;
1237 case ETHTOOL_SRXCLSRLDEL:
1238 ret = igc_del_ethtool_nfc_entry(adapter, cmd);
1239 default:
1240 break;
1241 }
1242
1243 return ret;
1244}
1245
646void igc_write_rss_indir_tbl(struct igc_adapter *adapter) 1246void igc_write_rss_indir_tbl(struct igc_adapter *adapter)
647{ 1247{
648 struct igc_hw *hw = &adapter->hw; 1248 struct igc_hw *hw = &adapter->hw;
@@ -1013,6 +1613,8 @@ static const struct ethtool_ops igc_ethtool_ops = {
1013 .set_pauseparam = igc_set_pauseparam, 1613 .set_pauseparam = igc_set_pauseparam,
1014 .get_coalesce = igc_get_coalesce, 1614 .get_coalesce = igc_get_coalesce,
1015 .set_coalesce = igc_set_coalesce, 1615 .set_coalesce = igc_set_coalesce,
1616 .get_rxnfc = igc_get_rxnfc,
1617 .set_rxnfc = igc_set_rxnfc,
1016 .get_rxfh_indir_size = igc_get_rxfh_indir_size, 1618 .get_rxfh_indir_size = igc_get_rxfh_indir_size,
1017 .get_rxfh = igc_get_rxfh, 1619 .get_rxfh = igc_get_rxfh,
1018 .set_rxfh = igc_set_rxfh, 1620 .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 a6fe614820b6..8460894829cb 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -1793,6 +1793,29 @@ static void igc_update_stats(struct igc_adapter *adapter)
1793 1793
1794static void igc_nfc_filter_exit(struct igc_adapter *adapter) 1794static void igc_nfc_filter_exit(struct igc_adapter *adapter)
1795{ 1795{
1796 struct igc_nfc_filter *rule;
1797
1798 spin_lock(&adapter->nfc_lock);
1799
1800 hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node)
1801 igc_erase_filter(adapter, rule);
1802
1803 hlist_for_each_entry(rule, &adapter->cls_flower_list, nfc_node)
1804 igc_erase_filter(adapter, rule);
1805
1806 spin_unlock(&adapter->nfc_lock);
1807}
1808
1809static void igc_nfc_filter_restore(struct igc_adapter *adapter)
1810{
1811 struct igc_nfc_filter *rule;
1812
1813 spin_lock(&adapter->nfc_lock);
1814
1815 hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node)
1816 igc_add_filter(adapter, rule);
1817
1818 spin_unlock(&adapter->nfc_lock);
1796} 1819}
1797 1820
1798/** 1821/**
@@ -1955,6 +1978,7 @@ static void igc_configure(struct igc_adapter *adapter)
1955 igc_setup_mrqc(adapter); 1978 igc_setup_mrqc(adapter);
1956 igc_setup_rctl(adapter); 1979 igc_setup_rctl(adapter);
1957 1980
1981 igc_nfc_filter_restore(adapter);
1958 igc_configure_tx(adapter); 1982 igc_configure_tx(adapter);
1959 igc_configure_rx(adapter); 1983 igc_configure_rx(adapter);
1960 1984
@@ -2016,6 +2040,127 @@ static void igc_set_default_mac_filter(struct igc_adapter *adapter)
2016 igc_rar_set_index(adapter, 0); 2040 igc_rar_set_index(adapter, 0);
2017} 2041}
2018 2042
2043/* If the filter to be added and an already existing filter express
2044 * the same address and address type, it should be possible to only
2045 * override the other configurations, for example the queue to steer
2046 * traffic.
2047 */
2048static bool igc_mac_entry_can_be_used(const struct igc_mac_addr *entry,
2049 const u8 *addr, const u8 flags)
2050{
2051 if (!(entry->state & IGC_MAC_STATE_IN_USE))
2052 return true;
2053
2054 if ((entry->state & IGC_MAC_STATE_SRC_ADDR) !=
2055 (flags & IGC_MAC_STATE_SRC_ADDR))
2056 return false;
2057
2058 if (!ether_addr_equal(addr, entry->addr))
2059 return false;
2060
2061 return true;
2062}
2063
2064/* Add a MAC filter for 'addr' directing matching traffic to 'queue',
2065 * 'flags' is used to indicate what kind of match is made, match is by
2066 * default for the destination address, if matching by source address
2067 * is desired the flag IGC_MAC_STATE_SRC_ADDR can be used.
2068 */
2069static int igc_add_mac_filter_flags(struct igc_adapter *adapter,
2070 const u8 *addr, const u8 queue,
2071 const u8 flags)
2072{
2073 struct igc_hw *hw = &adapter->hw;
2074 int rar_entries = hw->mac.rar_entry_count;
2075 int i;
2076
2077 if (is_zero_ether_addr(addr))
2078 return -EINVAL;
2079
2080 /* Search for the first empty entry in the MAC table.
2081 * Do not touch entries at the end of the table reserved for the VF MAC
2082 * addresses.
2083 */
2084 for (i = 0; i < rar_entries; i++) {
2085 if (!igc_mac_entry_can_be_used(&adapter->mac_table[i],
2086 addr, flags))
2087 continue;
2088
2089 ether_addr_copy(adapter->mac_table[i].addr, addr);
2090 adapter->mac_table[i].queue = queue;
2091 adapter->mac_table[i].state |= IGC_MAC_STATE_IN_USE | flags;
2092
2093 igc_rar_set_index(adapter, i);
2094 return i;
2095 }
2096
2097 return -ENOSPC;
2098}
2099
2100int igc_add_mac_steering_filter(struct igc_adapter *adapter,
2101 const u8 *addr, u8 queue, u8 flags)
2102{
2103 return igc_add_mac_filter_flags(adapter, addr, queue,
2104 IGC_MAC_STATE_QUEUE_STEERING | flags);
2105}
2106
2107/* Remove a MAC filter for 'addr' directing matching traffic to
2108 * 'queue', 'flags' is used to indicate what kind of match need to be
2109 * removed, match is by default for the destination address, if
2110 * matching by source address is to be removed the flag
2111 * IGC_MAC_STATE_SRC_ADDR can be used.
2112 */
2113static int igc_del_mac_filter_flags(struct igc_adapter *adapter,
2114 const u8 *addr, const u8 queue,
2115 const u8 flags)
2116{
2117 struct igc_hw *hw = &adapter->hw;
2118 int rar_entries = hw->mac.rar_entry_count;
2119 int i;
2120
2121 if (is_zero_ether_addr(addr))
2122 return -EINVAL;
2123
2124 /* Search for matching entry in the MAC table based on given address
2125 * and queue. Do not touch entries at the end of the table reserved
2126 * for the VF MAC addresses.
2127 */
2128 for (i = 0; i < rar_entries; i++) {
2129 if (!(adapter->mac_table[i].state & IGC_MAC_STATE_IN_USE))
2130 continue;
2131 if ((adapter->mac_table[i].state & flags) != flags)
2132 continue;
2133 if (adapter->mac_table[i].queue != queue)
2134 continue;
2135 if (!ether_addr_equal(adapter->mac_table[i].addr, addr))
2136 continue;
2137
2138 /* When a filter for the default address is "deleted",
2139 * we return it to its initial configuration
2140 */
2141 if (adapter->mac_table[i].state & IGC_MAC_STATE_DEFAULT) {
2142 adapter->mac_table[i].state =
2143 IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE;
2144 } else {
2145 adapter->mac_table[i].state = 0;
2146 adapter->mac_table[i].queue = 0;
2147 memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
2148 }
2149
2150 igc_rar_set_index(adapter, i);
2151 return 0;
2152 }
2153
2154 return -ENOENT;
2155}
2156
2157int igc_del_mac_steering_filter(struct igc_adapter *adapter,
2158 const u8 *addr, u8 queue, u8 flags)
2159{
2160 return igc_del_mac_filter_flags(adapter, addr, queue,
2161 IGC_MAC_STATE_QUEUE_STEERING | flags);
2162}
2163
2019/** 2164/**
2020 * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set 2165 * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
2021 * @netdev: network interface device structure 2166 * @netdev: network interface device structure
diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
index 325109cb20cc..50d7c04dccf5 100644
--- a/drivers/net/ethernet/intel/igc/igc_regs.h
+++ b/drivers/net/ethernet/intel/igc/igc_regs.h
@@ -83,6 +83,16 @@
83/* RSS registers */ 83/* RSS registers */
84#define IGC_MRQC 0x05818 /* Multiple Receive Control - RW */ 84#define IGC_MRQC 0x05818 /* Multiple Receive Control - RW */
85 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
86/* Redirection Table - RW Array */ 96/* Redirection Table - RW Array */
87#define IGC_RETA(_i) (0x05C00 + ((_i) * 4)) 97#define IGC_RETA(_i) (0x05C00 + ((_i) * 4))
88/* RSS Random Key - RW Array */ 98/* RSS Random Key - RW Array */
@@ -106,6 +116,7 @@
106#define IGC_UTA 0x0A000 /* Unicast Table Array - RW */ 116#define IGC_UTA 0x0A000 /* Unicast Table Array - RW */
107#define IGC_RAL(_n) (0x05400 + ((_n) * 0x08)) 117#define IGC_RAL(_n) (0x05400 + ((_n) * 0x08))
108#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 */
109 120
110/* Transmit Register Descriptions */ 121/* Transmit Register Descriptions */
111#define IGC_TCTL 0x00400 /* Tx Control - RW */ 122#define IGC_TCTL 0x00400 /* Tx Control - RW */