Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gianfar v5: implement nfc

This patch adds all missing functionalities for nfc except GRXFH. There is so much code because hardware has not a TCAM.
Further hardware rule space is very limited. So I had to extensively use
optimization features. Both reasons lead to the necessity to hold all
online flows in a linked-list.

Change-log:
# Some suggestions by Joe Perches applied (thanks!)
# Shorted some logs
# Use memcmp() for comparing

Signed-off-by: Sebastian Poehn <sebastian.poehn@belden.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Sebastian Poehn and committed by
David S. Miller
4aa3a715 d13d6bff

+989 -4
+7 -3
drivers/net/gianfar.c
··· 657 657 priv->num_rx_queues = num_rx_qs; 658 658 priv->num_grps = 0x0; 659 659 660 + /* Init Rx queue filer rule set linked list*/ 661 + INIT_LIST_HEAD(&priv->rx_list.list); 662 + priv->rx_list.count = 0; 663 + mutex_init(&priv->rx_queue_access); 664 + 660 665 model = of_get_property(np, "model", NULL); 661 666 662 667 for (i = 0; i < MAXGROUPS; i++) ··· 1155 1150 priv->rx_queue[i]->rxic = DEFAULT_RXIC; 1156 1151 } 1157 1152 1158 - /* enable filer if using multiple RX queues*/ 1159 - if(priv->num_rx_queues > 1) 1160 - priv->rx_filer_enable = 1; 1153 + /* always enable rx filer*/ 1154 + priv->rx_filer_enable = 1; 1161 1155 /* Enable most messages by default */ 1162 1156 priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; 1163 1157
+53
drivers/net/gianfar.h
··· 47 47 #include <linux/workqueue.h> 48 48 #include <linux/ethtool.h> 49 49 50 + struct ethtool_flow_spec_container { 51 + struct ethtool_rx_flow_spec fs; 52 + struct list_head list; 53 + }; 54 + 55 + struct ethtool_rx_list { 56 + struct list_head list; 57 + unsigned int count; 58 + }; 59 + 50 60 /* The maximum number of packets to be handled in one call of gfar_poll */ 51 61 #define GFAR_DEV_WEIGHT 64 52 62 ··· 178 168 #define MACCFG2_LENGTHCHECK 0x00000010 179 169 #define MACCFG2_MPEN 0x00000008 180 170 171 + #define ECNTRL_FIFM 0x00008000 181 172 #define ECNTRL_INIT_SETTINGS 0x00001000 182 173 #define ECNTRL_TBI_MODE 0x00000020 183 174 #define ECNTRL_REDUCED_MODE 0x00000010 ··· 282 271 #define RCTRL_TUCSEN 0x00000100 283 272 #define RCTRL_PRSDEP_MASK 0x000000c0 284 273 #define RCTRL_PRSDEP_INIT 0x000000c0 274 + #define RCTRL_PRSFM 0x00000020 285 275 #define RCTRL_PROM 0x00000008 286 276 #define RCTRL_EMEN 0x00000002 287 277 #define RCTRL_REQ_PARSER (RCTRL_VLEX | RCTRL_IPCSEN | \ ··· 1078 1066 1079 1067 struct vlan_group *vlgrp; 1080 1068 1069 + /* RX queue filer rule set*/ 1070 + struct ethtool_rx_list rx_list; 1071 + struct mutex rx_queue_access; 1081 1072 1082 1073 /* Hash registers and their width */ 1083 1074 u32 __iomem *hash_regs[16]; ··· 1155 1140 gfar_write(&regs->rqfpr, fpr); 1156 1141 } 1157 1142 1143 + static inline void gfar_read_filer(struct gfar_private *priv, 1144 + unsigned int far, unsigned int *fcr, unsigned int *fpr) 1145 + { 1146 + struct gfar __iomem *regs = priv->gfargrp[0].regs; 1147 + 1148 + gfar_write(&regs->rqfar, far); 1149 + *fcr = gfar_read(&regs->rqfcr); 1150 + *fpr = gfar_read(&regs->rqfpr); 1151 + } 1152 + 1158 1153 extern void lock_rx_qs(struct gfar_private *priv); 1159 1154 extern void lock_tx_qs(struct gfar_private *priv); 1160 1155 extern void unlock_rx_qs(struct gfar_private *priv); ··· 1181 1156 int gfar_set_features(struct net_device *dev, u32 features); 1182 1157 1183 1158 extern const struct ethtool_ops gfar_ethtool_ops; 1159 + 1160 + #define MAX_FILER_CACHE_IDX (2*(MAX_FILER_IDX)) 1161 + 1162 + #define RQFCR_PID_PRI_MASK 0xFFFFFFF8 1163 + #define RQFCR_PID_L4P_MASK 0xFFFFFF00 1164 + #define RQFCR_PID_VID_MASK 0xFFFFF000 1165 + #define RQFCR_PID_PORT_MASK 0xFFFF0000 1166 + #define RQFCR_PID_MAC_MASK 0xFF000000 1167 + 1168 + struct gfar_mask_entry { 1169 + unsigned int mask; /* The mask value which is valid form start to end */ 1170 + unsigned int start; 1171 + unsigned int end; 1172 + unsigned int block; /* Same block values indicate depended entries */ 1173 + }; 1174 + 1175 + /* Represents a receive filer table entry */ 1176 + struct gfar_filer_entry { 1177 + u32 ctrl; 1178 + u32 prop; 1179 + }; 1180 + 1181 + 1182 + /* The 20 additional entries are a shadow for one extra element */ 1183 + struct filer_table { 1184 + u32 index; 1185 + struct gfar_filer_entry fe[MAX_FILER_CACHE_IDX + 20]; 1186 + }; 1184 1187 1185 1188 #endif /* __GIANFAR_H */
+929 -1
drivers/net/gianfar_ethtool.c
··· 39 39 #include <linux/ethtool.h> 40 40 #include <linux/mii.h> 41 41 #include <linux/phy.h> 42 + #include <linux/sort.h> 42 43 43 44 #include "gianfar.h" 44 45 ··· 771 770 return 0; 772 771 } 773 772 773 + static int gfar_check_filer_hardware(struct gfar_private *priv) 774 + { 775 + struct gfar __iomem *regs = NULL; 776 + u32 i; 777 + 778 + regs = priv->gfargrp[0].regs; 779 + 780 + /* Check if we are in FIFO mode */ 781 + i = gfar_read(&regs->ecntrl); 782 + i &= ECNTRL_FIFM; 783 + if (i == ECNTRL_FIFM) { 784 + netdev_notice(priv->ndev, "Interface in FIFO mode\n"); 785 + i = gfar_read(&regs->rctrl); 786 + i &= RCTRL_PRSDEP_MASK | RCTRL_PRSFM; 787 + if (i == (RCTRL_PRSDEP_MASK | RCTRL_PRSFM)) { 788 + netdev_info(priv->ndev, 789 + "Receive Queue Filtering enabled\n"); 790 + } else { 791 + netdev_warn(priv->ndev, 792 + "Receive Queue Filtering disabled\n"); 793 + return -EOPNOTSUPP; 794 + } 795 + } 796 + /* Or in standard mode */ 797 + else { 798 + i = gfar_read(&regs->rctrl); 799 + i &= RCTRL_PRSDEP_MASK; 800 + if (i == RCTRL_PRSDEP_MASK) { 801 + netdev_info(priv->ndev, 802 + "Receive Queue Filtering enabled\n"); 803 + } else { 804 + netdev_warn(priv->ndev, 805 + "Receive Queue Filtering disabled\n"); 806 + return -EOPNOTSUPP; 807 + } 808 + } 809 + 810 + /* Sets the properties for arbitrary filer rule 811 + * to the first 4 Layer 4 Bytes */ 812 + regs->rbifx = 0xC0C1C2C3; 813 + return 0; 814 + } 815 + 816 + static int gfar_comp_asc(const void *a, const void *b) 817 + { 818 + return memcmp(a, b, 4); 819 + } 820 + 821 + static int gfar_comp_desc(const void *a, const void *b) 822 + { 823 + return -memcmp(a, b, 4); 824 + } 825 + 826 + static void gfar_swap(void *a, void *b, int size) 827 + { 828 + u32 *_a = a; 829 + u32 *_b = b; 830 + 831 + swap(_a[0], _b[0]); 832 + swap(_a[1], _b[1]); 833 + swap(_a[2], _b[2]); 834 + swap(_a[3], _b[3]); 835 + } 836 + 837 + /* Write a mask to filer cache */ 838 + static void gfar_set_mask(u32 mask, struct filer_table *tab) 839 + { 840 + tab->fe[tab->index].ctrl = RQFCR_AND | RQFCR_PID_MASK | RQFCR_CMP_EXACT; 841 + tab->fe[tab->index].prop = mask; 842 + tab->index++; 843 + } 844 + 845 + /* Sets parse bits (e.g. IP or TCP) */ 846 + static void gfar_set_parse_bits(u32 value, u32 mask, struct filer_table *tab) 847 + { 848 + gfar_set_mask(mask, tab); 849 + tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_PID_PARSE 850 + | RQFCR_AND; 851 + tab->fe[tab->index].prop = value; 852 + tab->index++; 853 + } 854 + 855 + static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag, 856 + struct filer_table *tab) 857 + { 858 + gfar_set_mask(mask, tab); 859 + tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_AND | flag; 860 + tab->fe[tab->index].prop = value; 861 + tab->index++; 862 + } 863 + 864 + /* 865 + * For setting a tuple of value and mask of type flag 866 + * Example: 867 + * IP-Src = 10.0.0.0/255.0.0.0 868 + * value: 0x0A000000 mask: FF000000 flag: RQFPR_IPV4 869 + * 870 + * Ethtool gives us a value=0 and mask=~0 for don't care a tuple 871 + * For a don't care mask it gives us a 0 872 + * 873 + * The check if don't care and the mask adjustment if mask=0 is done for VLAN 874 + * and MAC stuff on an upper level (due to missing information on this level). 875 + * For these guys we can discard them if they are value=0 and mask=0. 876 + * 877 + * Further the all masks are one-padded for better hardware efficiency. 878 + */ 879 + static void gfar_set_attribute(u32 value, u32 mask, u32 flag, 880 + struct filer_table *tab) 881 + { 882 + switch (flag) { 883 + /* 3bit */ 884 + case RQFCR_PID_PRI: 885 + if (!(value | mask)) 886 + return; 887 + mask |= RQFCR_PID_PRI_MASK; 888 + break; 889 + /* 8bit */ 890 + case RQFCR_PID_L4P: 891 + case RQFCR_PID_TOS: 892 + if (!~(mask | RQFCR_PID_L4P_MASK)) 893 + return; 894 + if (!mask) 895 + mask = ~0; 896 + else 897 + mask |= RQFCR_PID_L4P_MASK; 898 + break; 899 + /* 12bit */ 900 + case RQFCR_PID_VID: 901 + if (!(value | mask)) 902 + return; 903 + mask |= RQFCR_PID_VID_MASK; 904 + break; 905 + /* 16bit */ 906 + case RQFCR_PID_DPT: 907 + case RQFCR_PID_SPT: 908 + case RQFCR_PID_ETY: 909 + if (!~(mask | RQFCR_PID_PORT_MASK)) 910 + return; 911 + if (!mask) 912 + mask = ~0; 913 + else 914 + mask |= RQFCR_PID_PORT_MASK; 915 + break; 916 + /* 24bit */ 917 + case RQFCR_PID_DAH: 918 + case RQFCR_PID_DAL: 919 + case RQFCR_PID_SAH: 920 + case RQFCR_PID_SAL: 921 + if (!(value | mask)) 922 + return; 923 + mask |= RQFCR_PID_MAC_MASK; 924 + break; 925 + /* for all real 32bit masks */ 926 + default: 927 + if (!~mask) 928 + return; 929 + if (!mask) 930 + mask = ~0; 931 + break; 932 + } 933 + gfar_set_general_attribute(value, mask, flag, tab); 934 + } 935 + 936 + /* Translates value and mask for UDP, TCP or SCTP */ 937 + static void gfar_set_basic_ip(struct ethtool_tcpip4_spec *value, 938 + struct ethtool_tcpip4_spec *mask, struct filer_table *tab) 939 + { 940 + gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); 941 + gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); 942 + gfar_set_attribute(value->pdst, mask->pdst, RQFCR_PID_DPT, tab); 943 + gfar_set_attribute(value->psrc, mask->psrc, RQFCR_PID_SPT, tab); 944 + gfar_set_attribute(value->tos, mask->tos, RQFCR_PID_TOS, tab); 945 + } 946 + 947 + /* Translates value and mask for RAW-IP4 */ 948 + static void gfar_set_user_ip(struct ethtool_usrip4_spec *value, 949 + struct ethtool_usrip4_spec *mask, struct filer_table *tab) 950 + { 951 + gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); 952 + gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); 953 + gfar_set_attribute(value->tos, mask->tos, RQFCR_PID_TOS, tab); 954 + gfar_set_attribute(value->proto, mask->proto, RQFCR_PID_L4P, tab); 955 + gfar_set_attribute(value->l4_4_bytes, mask->l4_4_bytes, RQFCR_PID_ARB, 956 + tab); 957 + 958 + } 959 + 960 + /* Translates value and mask for ETHER spec */ 961 + static void gfar_set_ether(struct ethhdr *value, struct ethhdr *mask, 962 + struct filer_table *tab) 963 + { 964 + u32 upper_temp_mask = 0; 965 + u32 lower_temp_mask = 0; 966 + /* Source address */ 967 + if (!is_broadcast_ether_addr(mask->h_source)) { 968 + 969 + if (is_zero_ether_addr(mask->h_source)) { 970 + upper_temp_mask = 0xFFFFFFFF; 971 + lower_temp_mask = 0xFFFFFFFF; 972 + } else { 973 + upper_temp_mask = mask->h_source[0] << 16 974 + | mask->h_source[1] << 8 975 + | mask->h_source[2]; 976 + lower_temp_mask = mask->h_source[3] << 16 977 + | mask->h_source[4] << 8 978 + | mask->h_source[5]; 979 + } 980 + /* Upper 24bit */ 981 + gfar_set_attribute( 982 + value->h_source[0] << 16 | value->h_source[1] 983 + << 8 | value->h_source[2], 984 + upper_temp_mask, RQFCR_PID_SAH, tab); 985 + /* And the same for the lower part */ 986 + gfar_set_attribute( 987 + value->h_source[3] << 16 | value->h_source[4] 988 + << 8 | value->h_source[5], 989 + lower_temp_mask, RQFCR_PID_SAL, tab); 990 + } 991 + /* Destination address */ 992 + if (!is_broadcast_ether_addr(mask->h_dest)) { 993 + 994 + /* Special for destination is limited broadcast */ 995 + if ((is_broadcast_ether_addr(value->h_dest) 996 + && is_zero_ether_addr(mask->h_dest))) { 997 + gfar_set_parse_bits(RQFPR_EBC, RQFPR_EBC, tab); 998 + } else { 999 + 1000 + if (is_zero_ether_addr(mask->h_dest)) { 1001 + upper_temp_mask = 0xFFFFFFFF; 1002 + lower_temp_mask = 0xFFFFFFFF; 1003 + } else { 1004 + upper_temp_mask = mask->h_dest[0] << 16 1005 + | mask->h_dest[1] << 8 1006 + | mask->h_dest[2]; 1007 + lower_temp_mask = mask->h_dest[3] << 16 1008 + | mask->h_dest[4] << 8 1009 + | mask->h_dest[5]; 1010 + } 1011 + 1012 + /* Upper 24bit */ 1013 + gfar_set_attribute( 1014 + value->h_dest[0] << 16 1015 + | value->h_dest[1] << 8 1016 + | value->h_dest[2], 1017 + upper_temp_mask, RQFCR_PID_DAH, tab); 1018 + /* And the same for the lower part */ 1019 + gfar_set_attribute( 1020 + value->h_dest[3] << 16 1021 + | value->h_dest[4] << 8 1022 + | value->h_dest[5], 1023 + lower_temp_mask, RQFCR_PID_DAL, tab); 1024 + } 1025 + } 1026 + 1027 + gfar_set_attribute(value->h_proto, mask->h_proto, RQFCR_PID_ETY, tab); 1028 + 1029 + } 1030 + 1031 + /* Convert a rule to binary filter format of gianfar */ 1032 + static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, 1033 + struct filer_table *tab) 1034 + { 1035 + u32 vlan = 0, vlan_mask = 0; 1036 + u32 id = 0, id_mask = 0; 1037 + u32 cfi = 0, cfi_mask = 0; 1038 + u32 prio = 0, prio_mask = 0; 1039 + 1040 + u32 old_index = tab->index; 1041 + 1042 + /* Check if vlan is wanted */ 1043 + if ((rule->flow_type & FLOW_EXT) && (rule->m_ext.vlan_tci != 0xFFFF)) { 1044 + if (!rule->m_ext.vlan_tci) 1045 + rule->m_ext.vlan_tci = 0xFFFF; 1046 + 1047 + vlan = RQFPR_VLN; 1048 + vlan_mask = RQFPR_VLN; 1049 + 1050 + /* Separate the fields */ 1051 + id = rule->h_ext.vlan_tci & 0xFFF; 1052 + id_mask = rule->m_ext.vlan_tci & 0xFFF; 1053 + cfi = (rule->h_ext.vlan_tci >> 12) & 1; 1054 + cfi_mask = (rule->m_ext.vlan_tci >> 12) & 1; 1055 + prio = (rule->h_ext.vlan_tci >> 13) & 0x7; 1056 + prio_mask = (rule->m_ext.vlan_tci >> 13) & 0x7; 1057 + 1058 + if (cfi == 1 && cfi_mask == 1) { 1059 + vlan |= RQFPR_CFI; 1060 + vlan_mask |= RQFPR_CFI; 1061 + } else if (cfi == 0 && cfi_mask == 1) { 1062 + vlan_mask |= RQFPR_CFI; 1063 + } 1064 + } 1065 + 1066 + switch (rule->flow_type & ~FLOW_EXT) { 1067 + case TCP_V4_FLOW: 1068 + gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_TCP | vlan, 1069 + RQFPR_IPV4 | RQFPR_TCP | vlan_mask, tab); 1070 + gfar_set_basic_ip(&rule->h_u.tcp_ip4_spec, 1071 + &rule->m_u.tcp_ip4_spec, tab); 1072 + break; 1073 + case UDP_V4_FLOW: 1074 + gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_UDP | vlan, 1075 + RQFPR_IPV4 | RQFPR_UDP | vlan_mask, tab); 1076 + gfar_set_basic_ip(&rule->h_u.udp_ip4_spec, 1077 + &rule->m_u.udp_ip4_spec, tab); 1078 + break; 1079 + case SCTP_V4_FLOW: 1080 + gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, 1081 + tab); 1082 + gfar_set_attribute(132, 0, RQFCR_PID_L4P, tab); 1083 + gfar_set_basic_ip((struct ethtool_tcpip4_spec *) &rule->h_u, 1084 + (struct ethtool_tcpip4_spec *) &rule->m_u, tab); 1085 + break; 1086 + case IP_USER_FLOW: 1087 + gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, 1088 + tab); 1089 + gfar_set_user_ip((struct ethtool_usrip4_spec *) &rule->h_u, 1090 + (struct ethtool_usrip4_spec *) &rule->m_u, tab); 1091 + break; 1092 + case ETHER_FLOW: 1093 + if (vlan) 1094 + gfar_set_parse_bits(vlan, vlan_mask, tab); 1095 + gfar_set_ether((struct ethhdr *) &rule->h_u, 1096 + (struct ethhdr *) &rule->m_u, tab); 1097 + break; 1098 + default: 1099 + return -1; 1100 + } 1101 + 1102 + /* Set the vlan attributes in the end */ 1103 + if (vlan) { 1104 + gfar_set_attribute(id, id_mask, RQFCR_PID_VID, tab); 1105 + gfar_set_attribute(prio, prio_mask, RQFCR_PID_PRI, tab); 1106 + } 1107 + 1108 + /* If there has been nothing written till now, it must be a default */ 1109 + if (tab->index == old_index) { 1110 + gfar_set_mask(0xFFFFFFFF, tab); 1111 + tab->fe[tab->index].ctrl = 0x20; 1112 + tab->fe[tab->index].prop = 0x0; 1113 + tab->index++; 1114 + } 1115 + 1116 + /* Remove last AND */ 1117 + tab->fe[tab->index - 1].ctrl &= (~RQFCR_AND); 1118 + 1119 + /* Specify which queue to use or to drop */ 1120 + if (rule->ring_cookie == RX_CLS_FLOW_DISC) 1121 + tab->fe[tab->index - 1].ctrl |= RQFCR_RJE; 1122 + else 1123 + tab->fe[tab->index - 1].ctrl |= (rule->ring_cookie << 10); 1124 + 1125 + /* Only big enough entries can be clustered */ 1126 + if (tab->index > (old_index + 2)) { 1127 + tab->fe[old_index + 1].ctrl |= RQFCR_CLE; 1128 + tab->fe[tab->index - 1].ctrl |= RQFCR_CLE; 1129 + } 1130 + 1131 + /* In rare cases the cache can be full while there is free space in hw */ 1132 + if (tab->index > MAX_FILER_CACHE_IDX - 1) 1133 + return -EBUSY; 1134 + 1135 + return 0; 1136 + } 1137 + 1138 + /* Copy size filer entries */ 1139 + static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0], 1140 + struct gfar_filer_entry src[0], s32 size) 1141 + { 1142 + while (size > 0) { 1143 + size--; 1144 + dst[size].ctrl = src[size].ctrl; 1145 + dst[size].prop = src[size].prop; 1146 + } 1147 + } 1148 + 1149 + /* Delete the contents of the filer-table between start and end 1150 + * and collapse them */ 1151 + static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab) 1152 + { 1153 + int length; 1154 + if (end > MAX_FILER_CACHE_IDX || end < begin) 1155 + return -EINVAL; 1156 + 1157 + end++; 1158 + length = end - begin; 1159 + 1160 + /* Copy */ 1161 + while (end < tab->index) { 1162 + tab->fe[begin].ctrl = tab->fe[end].ctrl; 1163 + tab->fe[begin++].prop = tab->fe[end++].prop; 1164 + 1165 + } 1166 + /* Fill up with don't cares */ 1167 + while (begin < tab->index) { 1168 + tab->fe[begin].ctrl = 0x60; 1169 + tab->fe[begin].prop = 0xFFFFFFFF; 1170 + begin++; 1171 + } 1172 + 1173 + tab->index -= length; 1174 + return 0; 1175 + } 1176 + 1177 + /* Make space on the wanted location */ 1178 + static int gfar_expand_filer_entries(u32 begin, u32 length, 1179 + struct filer_table *tab) 1180 + { 1181 + if (length == 0 || length + tab->index > MAX_FILER_CACHE_IDX || begin 1182 + > MAX_FILER_CACHE_IDX) 1183 + return -EINVAL; 1184 + 1185 + gfar_copy_filer_entries(&(tab->fe[begin + length]), &(tab->fe[begin]), 1186 + tab->index - length + 1); 1187 + 1188 + tab->index += length; 1189 + return 0; 1190 + } 1191 + 1192 + static int gfar_get_next_cluster_start(int start, struct filer_table *tab) 1193 + { 1194 + for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) { 1195 + if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) 1196 + == (RQFCR_AND | RQFCR_CLE)) 1197 + return start; 1198 + } 1199 + return -1; 1200 + } 1201 + 1202 + static int gfar_get_next_cluster_end(int start, struct filer_table *tab) 1203 + { 1204 + for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) { 1205 + if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) 1206 + == (RQFCR_CLE)) 1207 + return start; 1208 + } 1209 + return -1; 1210 + } 1211 + 1212 + /* 1213 + * Uses hardwares clustering option to reduce 1214 + * the number of filer table entries 1215 + */ 1216 + static void gfar_cluster_filer(struct filer_table *tab) 1217 + { 1218 + s32 i = -1, j, iend, jend; 1219 + 1220 + while ((i = gfar_get_next_cluster_start(++i, tab)) != -1) { 1221 + j = i; 1222 + while ((j = gfar_get_next_cluster_start(++j, tab)) != -1) { 1223 + /* 1224 + * The cluster entries self and the previous one 1225 + * (a mask) must be identical! 1226 + */ 1227 + if (tab->fe[i].ctrl != tab->fe[j].ctrl) 1228 + break; 1229 + if (tab->fe[i].prop != tab->fe[j].prop) 1230 + break; 1231 + if (tab->fe[i - 1].ctrl != tab->fe[j - 1].ctrl) 1232 + break; 1233 + if (tab->fe[i - 1].prop != tab->fe[j - 1].prop) 1234 + break; 1235 + iend = gfar_get_next_cluster_end(i, tab); 1236 + jend = gfar_get_next_cluster_end(j, tab); 1237 + if (jend == -1 || iend == -1) 1238 + break; 1239 + /* 1240 + * First we make some free space, where our cluster 1241 + * element should be. Then we copy it there and finally 1242 + * delete in from its old location. 1243 + */ 1244 + 1245 + if (gfar_expand_filer_entries(iend, (jend - j), tab) 1246 + == -EINVAL) 1247 + break; 1248 + 1249 + gfar_copy_filer_entries(&(tab->fe[iend + 1]), 1250 + &(tab->fe[jend + 1]), jend - j); 1251 + 1252 + if (gfar_trim_filer_entries(jend - 1, 1253 + jend + (jend - j), tab) == -EINVAL) 1254 + return; 1255 + 1256 + /* Mask out cluster bit */ 1257 + tab->fe[iend].ctrl &= ~(RQFCR_CLE); 1258 + } 1259 + } 1260 + } 1261 + 1262 + /* Swaps the 0xFF80 masked bits of a1<>a2 and b1<>b2 */ 1263 + static void gfar_swap_ff80_bits(struct gfar_filer_entry *a1, 1264 + struct gfar_filer_entry *a2, struct gfar_filer_entry *b1, 1265 + struct gfar_filer_entry *b2) 1266 + { 1267 + u32 temp[4]; 1268 + temp[0] = a1->ctrl & 0xFF80; 1269 + temp[1] = a2->ctrl & 0xFF80; 1270 + temp[2] = b1->ctrl & 0xFF80; 1271 + temp[3] = b2->ctrl & 0xFF80; 1272 + 1273 + a1->ctrl &= ~0xFF80; 1274 + a2->ctrl &= ~0xFF80; 1275 + b1->ctrl &= ~0xFF80; 1276 + b2->ctrl &= ~0xFF80; 1277 + 1278 + a1->ctrl |= temp[1]; 1279 + a2->ctrl |= temp[0]; 1280 + b1->ctrl |= temp[3]; 1281 + b2->ctrl |= temp[2]; 1282 + } 1283 + 1284 + /* 1285 + * Generate a list consisting of masks values with their start and 1286 + * end of validity and block as indicator for parts belonging 1287 + * together (glued by ANDs) in mask_table 1288 + */ 1289 + static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, 1290 + struct filer_table *tab) 1291 + { 1292 + u32 i, and_index = 0, block_index = 1; 1293 + 1294 + for (i = 0; i < tab->index; i++) { 1295 + 1296 + /* LSByte of control = 0 sets a mask */ 1297 + if (!(tab->fe[i].ctrl & 0xF)) { 1298 + mask_table[and_index].mask = tab->fe[i].prop; 1299 + mask_table[and_index].start = i; 1300 + mask_table[and_index].block = block_index; 1301 + if (and_index >= 1) 1302 + mask_table[and_index - 1].end = i - 1; 1303 + and_index++; 1304 + } 1305 + /* cluster starts will be separated because they should 1306 + * hold their position */ 1307 + if (tab->fe[i].ctrl & RQFCR_CLE) 1308 + block_index++; 1309 + /* A not set AND indicates the end of a depended block */ 1310 + if (!(tab->fe[i].ctrl & RQFCR_AND)) 1311 + block_index++; 1312 + 1313 + } 1314 + 1315 + mask_table[and_index - 1].end = i - 1; 1316 + 1317 + return and_index; 1318 + } 1319 + 1320 + /* 1321 + * Sorts the entries of mask_table by the values of the masks. 1322 + * Important: The 0xFF80 flags of the first and last entry of a 1323 + * block must hold their position (which queue, CLusterEnable, ReJEct, 1324 + * AND) 1325 + */ 1326 + static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, 1327 + struct filer_table *temp_table, u32 and_index) 1328 + { 1329 + /* Pointer to compare function (_asc or _desc) */ 1330 + int (*gfar_comp)(const void *, const void *); 1331 + 1332 + u32 i, size = 0, start = 0, prev = 1; 1333 + u32 old_first, old_last, new_first, new_last; 1334 + 1335 + gfar_comp = &gfar_comp_desc; 1336 + 1337 + for (i = 0; i < and_index; i++) { 1338 + 1339 + if (prev != mask_table[i].block) { 1340 + old_first = mask_table[start].start + 1; 1341 + old_last = mask_table[i - 1].end; 1342 + sort(mask_table + start, size, 1343 + sizeof(struct gfar_mask_entry), 1344 + gfar_comp, &gfar_swap); 1345 + 1346 + /* Toggle order for every block. This makes the 1347 + * thing more efficient! */ 1348 + if (gfar_comp == gfar_comp_desc) 1349 + gfar_comp = &gfar_comp_asc; 1350 + else 1351 + gfar_comp = &gfar_comp_desc; 1352 + 1353 + new_first = mask_table[start].start + 1; 1354 + new_last = mask_table[i - 1].end; 1355 + 1356 + gfar_swap_ff80_bits(&temp_table->fe[new_first], 1357 + &temp_table->fe[old_first], 1358 + &temp_table->fe[new_last], 1359 + &temp_table->fe[old_last]); 1360 + 1361 + start = i; 1362 + size = 0; 1363 + } 1364 + size++; 1365 + prev = mask_table[i].block; 1366 + } 1367 + 1368 + } 1369 + 1370 + /* 1371 + * Reduces the number of masks needed in the filer table to save entries 1372 + * This is done by sorting the masks of a depended block. A depended block is 1373 + * identified by gluing ANDs or CLE. The sorting order toggles after every 1374 + * block. Of course entries in scope of a mask must change their location with 1375 + * it. 1376 + */ 1377 + static int gfar_optimize_filer_masks(struct filer_table *tab) 1378 + { 1379 + struct filer_table *temp_table; 1380 + struct gfar_mask_entry *mask_table; 1381 + 1382 + u32 and_index = 0, previous_mask = 0, i = 0, j = 0, size = 0; 1383 + s32 ret = 0; 1384 + 1385 + /* We need a copy of the filer table because 1386 + * we want to change its order */ 1387 + temp_table = kmalloc(sizeof(*temp_table), GFP_KERNEL); 1388 + if (temp_table == NULL) 1389 + return -ENOMEM; 1390 + memcpy(temp_table, tab, sizeof(*temp_table)); 1391 + 1392 + mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1, 1393 + sizeof(struct gfar_mask_entry), GFP_KERNEL); 1394 + 1395 + if (mask_table == NULL) { 1396 + ret = -ENOMEM; 1397 + goto end; 1398 + } 1399 + 1400 + and_index = gfar_generate_mask_table(mask_table, tab); 1401 + 1402 + gfar_sort_mask_table(mask_table, temp_table, and_index); 1403 + 1404 + /* Now we can copy the data from our duplicated filer table to 1405 + * the real one in the order the mask table says */ 1406 + for (i = 0; i < and_index; i++) { 1407 + size = mask_table[i].end - mask_table[i].start + 1; 1408 + gfar_copy_filer_entries(&(tab->fe[j]), 1409 + &(temp_table->fe[mask_table[i].start]), size); 1410 + j += size; 1411 + } 1412 + 1413 + /* And finally we just have to check for duplicated masks and drop the 1414 + * second ones */ 1415 + for (i = 0; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) { 1416 + if (tab->fe[i].ctrl == 0x80) { 1417 + previous_mask = i++; 1418 + break; 1419 + } 1420 + } 1421 + for (; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) { 1422 + if (tab->fe[i].ctrl == 0x80) { 1423 + if (tab->fe[i].prop == tab->fe[previous_mask].prop) { 1424 + /* Two identical ones found! 1425 + * So drop the second one! */ 1426 + gfar_trim_filer_entries(i, i, tab); 1427 + } else 1428 + /* Not identical! */ 1429 + previous_mask = i; 1430 + } 1431 + } 1432 + 1433 + kfree(mask_table); 1434 + end: kfree(temp_table); 1435 + return ret; 1436 + } 1437 + 1438 + /* Write the bit-pattern from software's buffer to hardware registers */ 1439 + static int gfar_write_filer_table(struct gfar_private *priv, 1440 + struct filer_table *tab) 1441 + { 1442 + u32 i = 0; 1443 + if (tab->index > MAX_FILER_IDX - 1) 1444 + return -EBUSY; 1445 + 1446 + /* Avoid inconsistent filer table to be processed */ 1447 + lock_rx_qs(priv); 1448 + 1449 + /* Fill regular entries */ 1450 + for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl); i++) 1451 + gfar_write_filer(priv, i, tab->fe[i].ctrl, tab->fe[i].prop); 1452 + /* Fill the rest with fall-troughs */ 1453 + for (; i < MAX_FILER_IDX - 1; i++) 1454 + gfar_write_filer(priv, i, 0x60, 0xFFFFFFFF); 1455 + /* Last entry must be default accept 1456 + * because that's what people expect */ 1457 + gfar_write_filer(priv, i, 0x20, 0x0); 1458 + 1459 + unlock_rx_qs(priv); 1460 + 1461 + return 0; 1462 + } 1463 + 1464 + static int gfar_check_capability(struct ethtool_rx_flow_spec *flow, 1465 + struct gfar_private *priv) 1466 + { 1467 + 1468 + if (flow->flow_type & FLOW_EXT) { 1469 + if (~flow->m_ext.data[0] || ~flow->m_ext.data[1]) 1470 + netdev_warn(priv->ndev, 1471 + "User-specific data not supported!\n"); 1472 + if (~flow->m_ext.vlan_etype) 1473 + netdev_warn(priv->ndev, 1474 + "VLAN-etype not supported!\n"); 1475 + } 1476 + if (flow->flow_type == IP_USER_FLOW) 1477 + if (flow->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4) 1478 + netdev_warn(priv->ndev, 1479 + "IP-Version differing from IPv4 not supported!\n"); 1480 + 1481 + return 0; 1482 + } 1483 + 1484 + static int gfar_process_filer_changes(struct gfar_private *priv) 1485 + { 1486 + struct ethtool_flow_spec_container *j; 1487 + struct filer_table *tab; 1488 + s32 i = 0; 1489 + s32 ret = 0; 1490 + 1491 + /* So index is set to zero, too! */ 1492 + tab = kzalloc(sizeof(*tab), GFP_KERNEL); 1493 + if (tab == NULL) 1494 + return -ENOMEM; 1495 + 1496 + /* Now convert the existing filer data from flow_spec into 1497 + * filer tables binary format */ 1498 + list_for_each_entry(j, &priv->rx_list.list, list) { 1499 + ret = gfar_convert_to_filer(&j->fs, tab); 1500 + if (ret == -EBUSY) { 1501 + netdev_err(priv->ndev, "Rule not added: No free space!\n"); 1502 + goto end; 1503 + } 1504 + if (ret == -1) { 1505 + netdev_err(priv->ndev, "Rule not added: Unsupported Flow-type!\n"); 1506 + goto end; 1507 + } 1508 + } 1509 + 1510 + i = tab->index; 1511 + 1512 + /* Optimizations to save entries */ 1513 + gfar_cluster_filer(tab); 1514 + gfar_optimize_filer_masks(tab); 1515 + 1516 + pr_debug("\n\tSummary:\n" 1517 + "\tData on hardware: %d\n" 1518 + "\tCompression rate: %d%%\n", 1519 + tab->index, 100 - (100 * tab->index) / i); 1520 + 1521 + /* Write everything to hardware */ 1522 + ret = gfar_write_filer_table(priv, tab); 1523 + if (ret == -EBUSY) { 1524 + netdev_err(priv->ndev, "Rule not added: No free space!\n"); 1525 + goto end; 1526 + } 1527 + 1528 + end: kfree(tab); 1529 + return ret; 1530 + } 1531 + 1532 + static void gfar_invert_masks(struct ethtool_rx_flow_spec *flow) 1533 + { 1534 + u32 i = 0; 1535 + 1536 + for (i = 0; i < sizeof(flow->m_u); i++) 1537 + flow->m_u.hdata[i] ^= 0xFF; 1538 + 1539 + flow->m_ext.vlan_etype ^= 0xFFFF; 1540 + flow->m_ext.vlan_tci ^= 0xFFFF; 1541 + flow->m_ext.data[0] ^= ~0; 1542 + flow->m_ext.data[1] ^= ~0; 1543 + } 1544 + 1545 + static int gfar_add_cls(struct gfar_private *priv, 1546 + struct ethtool_rx_flow_spec *flow) 1547 + { 1548 + struct ethtool_flow_spec_container *temp, *comp; 1549 + int ret = 0; 1550 + 1551 + temp = kmalloc(sizeof(*temp), GFP_KERNEL); 1552 + if (temp == NULL) 1553 + return -ENOMEM; 1554 + memcpy(&temp->fs, flow, sizeof(temp->fs)); 1555 + 1556 + gfar_invert_masks(&temp->fs); 1557 + ret = gfar_check_capability(&temp->fs, priv); 1558 + if (ret) 1559 + goto clean_mem; 1560 + /* Link in the new element at the right @location */ 1561 + if (list_empty(&priv->rx_list.list)) { 1562 + ret = gfar_check_filer_hardware(priv); 1563 + if (ret != 0) 1564 + goto clean_mem; 1565 + list_add(&temp->list, &priv->rx_list.list); 1566 + goto process; 1567 + } else { 1568 + 1569 + list_for_each_entry(comp, &priv->rx_list.list, list) { 1570 + if (comp->fs.location > flow->location) { 1571 + list_add_tail(&temp->list, &comp->list); 1572 + goto process; 1573 + } 1574 + if (comp->fs.location == flow->location) { 1575 + netdev_err(priv->ndev, 1576 + "Rule not added: ID %d not free!\n", 1577 + flow->location); 1578 + ret = -EBUSY; 1579 + goto clean_mem; 1580 + } 1581 + } 1582 + list_add_tail(&temp->list, &priv->rx_list.list); 1583 + } 1584 + 1585 + process: 1586 + ret = gfar_process_filer_changes(priv); 1587 + if (ret) 1588 + goto clean_list; 1589 + priv->rx_list.count++; 1590 + return ret; 1591 + 1592 + clean_list: 1593 + list_del(&temp->list); 1594 + clean_mem: 1595 + kfree(temp); 1596 + return ret; 1597 + } 1598 + 1599 + static int gfar_del_cls(struct gfar_private *priv, u32 loc) 1600 + { 1601 + struct ethtool_flow_spec_container *comp; 1602 + u32 ret = -EINVAL; 1603 + 1604 + if (list_empty(&priv->rx_list.list)) 1605 + return ret; 1606 + 1607 + list_for_each_entry(comp, &priv->rx_list.list, list) { 1608 + if (comp->fs.location == loc) { 1609 + list_del(&comp->list); 1610 + kfree(comp); 1611 + priv->rx_list.count--; 1612 + gfar_process_filer_changes(priv); 1613 + ret = 0; 1614 + break; 1615 + } 1616 + } 1617 + 1618 + return ret; 1619 + 1620 + } 1621 + 1622 + static int gfar_get_cls(struct gfar_private *priv, struct ethtool_rxnfc *cmd) 1623 + { 1624 + struct ethtool_flow_spec_container *comp; 1625 + u32 ret = -EINVAL; 1626 + 1627 + list_for_each_entry(comp, &priv->rx_list.list, list) { 1628 + if (comp->fs.location == cmd->fs.location) { 1629 + memcpy(&cmd->fs, &comp->fs, sizeof(cmd->fs)); 1630 + gfar_invert_masks(&cmd->fs); 1631 + ret = 0; 1632 + break; 1633 + } 1634 + } 1635 + 1636 + return ret; 1637 + } 1638 + 1639 + static int gfar_get_cls_all(struct gfar_private *priv, 1640 + struct ethtool_rxnfc *cmd, u32 *rule_locs) 1641 + { 1642 + struct ethtool_flow_spec_container *comp; 1643 + u32 i = 0; 1644 + 1645 + list_for_each_entry(comp, &priv->rx_list.list, list) { 1646 + if (i <= cmd->rule_cnt) { 1647 + rule_locs[i] = comp->fs.location; 1648 + i++; 1649 + } 1650 + } 1651 + 1652 + cmd->data = MAX_FILER_IDX; 1653 + 1654 + return 0; 1655 + } 1656 + 774 1657 static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd) 775 1658 { 776 1659 struct gfar_private *priv = netdev_priv(dev); 777 1660 int ret = 0; 778 1661 779 - switch(cmd->cmd) { 1662 + mutex_lock(&priv->rx_queue_access); 1663 + 1664 + switch (cmd->cmd) { 780 1665 case ETHTOOL_SRXFH: 781 1666 ret = gfar_set_hash_opts(priv, cmd); 782 1667 break; 1668 + case ETHTOOL_SRXCLSRLINS: 1669 + if (cmd->fs.ring_cookie != RX_CLS_FLOW_DISC && 1670 + cmd->fs.ring_cookie >= priv->num_rx_queues) { 1671 + ret = -EINVAL; 1672 + break; 1673 + } 1674 + ret = gfar_add_cls(priv, &cmd->fs); 1675 + break; 1676 + case ETHTOOL_SRXCLSRLDEL: 1677 + ret = gfar_del_cls(priv, cmd->fs.location); 1678 + break; 783 1679 default: 784 1680 ret = -EINVAL; 1681 + } 1682 + 1683 + mutex_unlock(&priv->rx_queue_access); 1684 + 1685 + return ret; 1686 + } 1687 + 1688 + static int gfar_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, 1689 + void *rule_locs) 1690 + { 1691 + struct gfar_private *priv = netdev_priv(dev); 1692 + int ret = 0; 1693 + 1694 + switch (cmd->cmd) { 1695 + case ETHTOOL_GRXRINGS: 1696 + cmd->data = priv->num_rx_queues; 1697 + break; 1698 + case ETHTOOL_GRXCLSRLCNT: 1699 + cmd->rule_cnt = priv->rx_list.count; 1700 + break; 1701 + case ETHTOOL_GRXCLSRULE: 1702 + ret = gfar_get_cls(priv, cmd); 1703 + break; 1704 + case ETHTOOL_GRXCLSRLALL: 1705 + ret = gfar_get_cls_all(priv, cmd, (u32 *) rule_locs); 1706 + break; 1707 + default: 1708 + ret = -EINVAL; 1709 + break; 785 1710 } 786 1711 787 1712 return ret; ··· 1734 807 .set_wol = gfar_set_wol, 1735 808 #endif 1736 809 .set_rxnfc = gfar_set_nfc, 810 + .get_rxnfc = gfar_get_nfc, 1737 811 };