0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifndef __CXGB4_TC_U32_PARSE_H
0036 #define __CXGB4_TC_U32_PARSE_H
0037
0038 struct cxgb4_match_field {
0039 int off;
0040
0041 int (*val)(struct ch_filter_specification *f, __be32 val, __be32 mask);
0042 };
0043
0044
0045 static inline int cxgb4_fill_ipv4_tos(struct ch_filter_specification *f,
0046 __be32 val, __be32 mask)
0047 {
0048 f->val.tos = (ntohl(val) >> 16) & 0x000000FF;
0049 f->mask.tos = (ntohl(mask) >> 16) & 0x000000FF;
0050
0051 return 0;
0052 }
0053
0054 static inline int cxgb4_fill_ipv4_frag(struct ch_filter_specification *f,
0055 __be32 val, __be32 mask)
0056 {
0057 u32 mask_val;
0058 u8 frag_val;
0059
0060 frag_val = (ntohl(val) >> 13) & 0x00000007;
0061 mask_val = ntohl(mask) & 0x0000FFFF;
0062
0063 if (frag_val == 0x1 && mask_val != 0x3FFF) {
0064 f->val.frag = 1;
0065 f->mask.frag = 1;
0066 } else if (frag_val == 0x2 && mask_val != 0x3FFF) {
0067 f->val.frag = 0;
0068 f->mask.frag = 1;
0069 } else {
0070 return -EINVAL;
0071 }
0072
0073 return 0;
0074 }
0075
0076 static inline int cxgb4_fill_ipv4_proto(struct ch_filter_specification *f,
0077 __be32 val, __be32 mask)
0078 {
0079 f->val.proto = (ntohl(val) >> 16) & 0x000000FF;
0080 f->mask.proto = (ntohl(mask) >> 16) & 0x000000FF;
0081
0082 return 0;
0083 }
0084
0085 static inline int cxgb4_fill_ipv4_src_ip(struct ch_filter_specification *f,
0086 __be32 val, __be32 mask)
0087 {
0088 memcpy(&f->val.fip[0], &val, sizeof(u32));
0089 memcpy(&f->mask.fip[0], &mask, sizeof(u32));
0090
0091 return 0;
0092 }
0093
0094 static inline int cxgb4_fill_ipv4_dst_ip(struct ch_filter_specification *f,
0095 __be32 val, __be32 mask)
0096 {
0097 memcpy(&f->val.lip[0], &val, sizeof(u32));
0098 memcpy(&f->mask.lip[0], &mask, sizeof(u32));
0099
0100 return 0;
0101 }
0102
0103 static const struct cxgb4_match_field cxgb4_ipv4_fields[] = {
0104 { .off = 0, .val = cxgb4_fill_ipv4_tos },
0105 { .off = 4, .val = cxgb4_fill_ipv4_frag },
0106 { .off = 8, .val = cxgb4_fill_ipv4_proto },
0107 { .off = 12, .val = cxgb4_fill_ipv4_src_ip },
0108 { .off = 16, .val = cxgb4_fill_ipv4_dst_ip },
0109 { .val = NULL }
0110 };
0111
0112
0113 static inline int cxgb4_fill_ipv6_tos(struct ch_filter_specification *f,
0114 __be32 val, __be32 mask)
0115 {
0116 f->val.tos = (ntohl(val) >> 20) & 0x000000FF;
0117 f->mask.tos = (ntohl(mask) >> 20) & 0x000000FF;
0118
0119 return 0;
0120 }
0121
0122 static inline int cxgb4_fill_ipv6_proto(struct ch_filter_specification *f,
0123 __be32 val, __be32 mask)
0124 {
0125 f->val.proto = (ntohl(val) >> 8) & 0x000000FF;
0126 f->mask.proto = (ntohl(mask) >> 8) & 0x000000FF;
0127
0128 return 0;
0129 }
0130
0131 static inline int cxgb4_fill_ipv6_src_ip0(struct ch_filter_specification *f,
0132 __be32 val, __be32 mask)
0133 {
0134 memcpy(&f->val.fip[0], &val, sizeof(u32));
0135 memcpy(&f->mask.fip[0], &mask, sizeof(u32));
0136
0137 return 0;
0138 }
0139
0140 static inline int cxgb4_fill_ipv6_src_ip1(struct ch_filter_specification *f,
0141 __be32 val, __be32 mask)
0142 {
0143 memcpy(&f->val.fip[4], &val, sizeof(u32));
0144 memcpy(&f->mask.fip[4], &mask, sizeof(u32));
0145
0146 return 0;
0147 }
0148
0149 static inline int cxgb4_fill_ipv6_src_ip2(struct ch_filter_specification *f,
0150 __be32 val, __be32 mask)
0151 {
0152 memcpy(&f->val.fip[8], &val, sizeof(u32));
0153 memcpy(&f->mask.fip[8], &mask, sizeof(u32));
0154
0155 return 0;
0156 }
0157
0158 static inline int cxgb4_fill_ipv6_src_ip3(struct ch_filter_specification *f,
0159 __be32 val, __be32 mask)
0160 {
0161 memcpy(&f->val.fip[12], &val, sizeof(u32));
0162 memcpy(&f->mask.fip[12], &mask, sizeof(u32));
0163
0164 return 0;
0165 }
0166
0167 static inline int cxgb4_fill_ipv6_dst_ip0(struct ch_filter_specification *f,
0168 __be32 val, __be32 mask)
0169 {
0170 memcpy(&f->val.lip[0], &val, sizeof(u32));
0171 memcpy(&f->mask.lip[0], &mask, sizeof(u32));
0172
0173 return 0;
0174 }
0175
0176 static inline int cxgb4_fill_ipv6_dst_ip1(struct ch_filter_specification *f,
0177 __be32 val, __be32 mask)
0178 {
0179 memcpy(&f->val.lip[4], &val, sizeof(u32));
0180 memcpy(&f->mask.lip[4], &mask, sizeof(u32));
0181
0182 return 0;
0183 }
0184
0185 static inline int cxgb4_fill_ipv6_dst_ip2(struct ch_filter_specification *f,
0186 __be32 val, __be32 mask)
0187 {
0188 memcpy(&f->val.lip[8], &val, sizeof(u32));
0189 memcpy(&f->mask.lip[8], &mask, sizeof(u32));
0190
0191 return 0;
0192 }
0193
0194 static inline int cxgb4_fill_ipv6_dst_ip3(struct ch_filter_specification *f,
0195 __be32 val, __be32 mask)
0196 {
0197 memcpy(&f->val.lip[12], &val, sizeof(u32));
0198 memcpy(&f->mask.lip[12], &mask, sizeof(u32));
0199
0200 return 0;
0201 }
0202
0203 static const struct cxgb4_match_field cxgb4_ipv6_fields[] = {
0204 { .off = 0, .val = cxgb4_fill_ipv6_tos },
0205 { .off = 4, .val = cxgb4_fill_ipv6_proto },
0206 { .off = 8, .val = cxgb4_fill_ipv6_src_ip0 },
0207 { .off = 12, .val = cxgb4_fill_ipv6_src_ip1 },
0208 { .off = 16, .val = cxgb4_fill_ipv6_src_ip2 },
0209 { .off = 20, .val = cxgb4_fill_ipv6_src_ip3 },
0210 { .off = 24, .val = cxgb4_fill_ipv6_dst_ip0 },
0211 { .off = 28, .val = cxgb4_fill_ipv6_dst_ip1 },
0212 { .off = 32, .val = cxgb4_fill_ipv6_dst_ip2 },
0213 { .off = 36, .val = cxgb4_fill_ipv6_dst_ip3 },
0214 { .val = NULL }
0215 };
0216
0217
0218 static inline int cxgb4_fill_l4_ports(struct ch_filter_specification *f,
0219 __be32 val, __be32 mask)
0220 {
0221 f->val.fport = ntohl(val) >> 16;
0222 f->mask.fport = ntohl(mask) >> 16;
0223 f->val.lport = ntohl(val) & 0x0000FFFF;
0224 f->mask.lport = ntohl(mask) & 0x0000FFFF;
0225
0226 return 0;
0227 };
0228
0229 static const struct cxgb4_match_field cxgb4_tcp_fields[] = {
0230 { .off = 0, .val = cxgb4_fill_l4_ports },
0231 { .val = NULL }
0232 };
0233
0234 static const struct cxgb4_match_field cxgb4_udp_fields[] = {
0235 { .off = 0, .val = cxgb4_fill_l4_ports },
0236 { .val = NULL }
0237 };
0238
0239 struct cxgb4_next_header {
0240
0241
0242
0243
0244
0245 struct tc_u32_sel sel;
0246 struct tc_u32_key key;
0247
0248 const struct cxgb4_match_field *jump;
0249 };
0250
0251
0252
0253
0254 static const struct cxgb4_next_header cxgb4_ipv4_jumps[] = {
0255 {
0256
0257 .sel = {
0258 .off = 0,
0259 .offoff = 0,
0260 .offshift = 6,
0261 .offmask = cpu_to_be16(0x0f00),
0262 },
0263 .key = {
0264 .off = 8,
0265 .val = cpu_to_be32(0x00060000),
0266 .mask = cpu_to_be32(0x00ff0000),
0267 },
0268 .jump = cxgb4_tcp_fields,
0269 },
0270 {
0271
0272 .sel = {
0273 .off = 0,
0274 .offoff = 0,
0275 .offshift = 6,
0276 .offmask = cpu_to_be16(0x0f00),
0277 },
0278 .key = {
0279 .off = 8,
0280 .val = cpu_to_be32(0x00110000),
0281 .mask = cpu_to_be32(0x00ff0000),
0282 },
0283 .jump = cxgb4_udp_fields,
0284 },
0285 { .jump = NULL },
0286 };
0287
0288
0289
0290
0291 static const struct cxgb4_next_header cxgb4_ipv6_jumps[] = {
0292 {
0293
0294 .sel = {
0295 .off = 40,
0296 .offoff = 0,
0297 .offshift = 0,
0298 .offmask = 0,
0299 },
0300 .key = {
0301 .off = 4,
0302 .val = cpu_to_be32(0x00000600),
0303 .mask = cpu_to_be32(0x0000ff00),
0304 },
0305 .jump = cxgb4_tcp_fields,
0306 },
0307 {
0308
0309 .sel = {
0310 .off = 40,
0311 .offoff = 0,
0312 .offshift = 0,
0313 .offmask = 0,
0314 },
0315 .key = {
0316 .off = 4,
0317 .val = cpu_to_be32(0x00001100),
0318 .mask = cpu_to_be32(0x0000ff00),
0319 },
0320 .jump = cxgb4_udp_fields,
0321 },
0322 { .jump = NULL },
0323 };
0324
0325 struct cxgb4_link {
0326 const struct cxgb4_match_field *match_field;
0327 struct ch_filter_specification fs;
0328 u32 link_handle;
0329 unsigned long *tid_map;
0330 };
0331
0332 struct cxgb4_tc_u32_table {
0333 unsigned int size;
0334 struct cxgb4_link table[];
0335 };
0336 #endif