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

Merge tag 'mlx5-updates-2019-11-01' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-updates-2019-11-01

Misc updates for mlx5 netdev and core driver

1) Steering Core: Replace CRC32 internal implementation with standard
kernel lib.
2) Steering Core: Support IPv4 and IPv6 mixed matcher.
3) Steering Core: Lockless FTE read lookups
4) TC: Bit sized fields rewrite support.
5) FPGA: Standalone FPGA support.
6) SRIOV: Reset VF parameters configurations on SRIOV disable.
7) netdev: Dump WQs wqe descriptors on CQE with error events.
8) MISC Cleanups.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+393 -359
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/Makefile
··· 70 70 71 71 mlx5_core-$(CONFIG_MLX5_SW_STEERING) += steering/dr_domain.o steering/dr_table.o \ 72 72 steering/dr_matcher.o steering/dr_rule.o \ 73 - steering/dr_icm_pool.o steering/dr_crc32.o \ 73 + steering/dr_icm_pool.o \ 74 74 steering/dr_ste.o steering/dr_send.o \ 75 75 steering/dr_cmd.o steering/dr_fw.o \ 76 76 steering/dr_action.o steering/fs_dr.o
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
··· 866 866 if (!ent->page_queue) { 867 867 alloc_ret = alloc_ent(cmd); 868 868 if (alloc_ret < 0) { 869 - mlx5_core_err(dev, "failed to allocate command entry\n"); 869 + mlx5_core_err_rl(dev, "failed to allocate command entry\n"); 870 870 if (ent->callback) { 871 871 ent->callback(-EAGAIN, ent->context); 872 872 mlx5_free_cmd_msg(dev, ent->out);
+67 -58
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
··· 2241 2241 2242 2242 struct mlx5_fields { 2243 2243 u8 field; 2244 - u8 size; 2244 + u8 field_bsize; 2245 + u32 field_mask; 2245 2246 u32 offset; 2246 2247 u32 match_offset; 2247 2248 }; 2248 2249 2249 - #define OFFLOAD(fw_field, size, field, off, match_field) \ 2250 - {MLX5_ACTION_IN_FIELD_OUT_ ## fw_field, size, \ 2250 + #define OFFLOAD(fw_field, field_bsize, field_mask, field, off, match_field) \ 2251 + {MLX5_ACTION_IN_FIELD_OUT_ ## fw_field, field_bsize, field_mask, \ 2251 2252 offsetof(struct pedit_headers, field) + (off), \ 2252 2253 MLX5_BYTE_OFF(fte_match_set_lyr_2_4, match_field)} 2253 2254 ··· 2266 2265 }) 2267 2266 2268 2267 static bool cmp_val_mask(void *valp, void *maskp, void *matchvalp, 2269 - void *matchmaskp, int size) 2268 + void *matchmaskp, u8 bsize) 2270 2269 { 2271 2270 bool same = false; 2272 2271 2273 - switch (size) { 2274 - case sizeof(u8): 2272 + switch (bsize) { 2273 + case 8: 2275 2274 same = SAME_VAL_MASK(u8, valp, maskp, matchvalp, matchmaskp); 2276 2275 break; 2277 - case sizeof(u16): 2276 + case 16: 2278 2277 same = SAME_VAL_MASK(u16, valp, maskp, matchvalp, matchmaskp); 2279 2278 break; 2280 - case sizeof(u32): 2279 + case 32: 2281 2280 same = SAME_VAL_MASK(u32, valp, maskp, matchvalp, matchmaskp); 2282 2281 break; 2283 2282 } ··· 2286 2285 } 2287 2286 2288 2287 static struct mlx5_fields fields[] = { 2289 - OFFLOAD(DMAC_47_16, 4, eth.h_dest[0], 0, dmac_47_16), 2290 - OFFLOAD(DMAC_15_0, 2, eth.h_dest[4], 0, dmac_15_0), 2291 - OFFLOAD(SMAC_47_16, 4, eth.h_source[0], 0, smac_47_16), 2292 - OFFLOAD(SMAC_15_0, 2, eth.h_source[4], 0, smac_15_0), 2293 - OFFLOAD(ETHERTYPE, 2, eth.h_proto, 0, ethertype), 2294 - OFFLOAD(FIRST_VID, 2, vlan.h_vlan_TCI, 0, first_vid), 2288 + OFFLOAD(DMAC_47_16, 32, U32_MAX, eth.h_dest[0], 0, dmac_47_16), 2289 + OFFLOAD(DMAC_15_0, 16, U16_MAX, eth.h_dest[4], 0, dmac_15_0), 2290 + OFFLOAD(SMAC_47_16, 32, U32_MAX, eth.h_source[0], 0, smac_47_16), 2291 + OFFLOAD(SMAC_15_0, 16, U16_MAX, eth.h_source[4], 0, smac_15_0), 2292 + OFFLOAD(ETHERTYPE, 16, U16_MAX, eth.h_proto, 0, ethertype), 2293 + OFFLOAD(FIRST_VID, 16, U16_MAX, vlan.h_vlan_TCI, 0, first_vid), 2295 2294 2296 - OFFLOAD(IP_TTL, 1, ip4.ttl, 0, ttl_hoplimit), 2297 - OFFLOAD(SIPV4, 4, ip4.saddr, 0, src_ipv4_src_ipv6.ipv4_layout.ipv4), 2298 - OFFLOAD(DIPV4, 4, ip4.daddr, 0, dst_ipv4_dst_ipv6.ipv4_layout.ipv4), 2295 + OFFLOAD(IP_DSCP, 8, 0xfc, ip4.tos, 0, ip_dscp), 2296 + OFFLOAD(IP_TTL, 8, U8_MAX, ip4.ttl, 0, ttl_hoplimit), 2297 + OFFLOAD(SIPV4, 32, U32_MAX, ip4.saddr, 0, src_ipv4_src_ipv6.ipv4_layout.ipv4), 2298 + OFFLOAD(DIPV4, 32, U32_MAX, ip4.daddr, 0, dst_ipv4_dst_ipv6.ipv4_layout.ipv4), 2299 2299 2300 - OFFLOAD(SIPV6_127_96, 4, ip6.saddr.s6_addr32[0], 0, 2300 + OFFLOAD(SIPV6_127_96, 32, U32_MAX, ip6.saddr.s6_addr32[0], 0, 2301 2301 src_ipv4_src_ipv6.ipv6_layout.ipv6[0]), 2302 - OFFLOAD(SIPV6_95_64, 4, ip6.saddr.s6_addr32[1], 0, 2302 + OFFLOAD(SIPV6_95_64, 32, U32_MAX, ip6.saddr.s6_addr32[1], 0, 2303 2303 src_ipv4_src_ipv6.ipv6_layout.ipv6[4]), 2304 - OFFLOAD(SIPV6_63_32, 4, ip6.saddr.s6_addr32[2], 0, 2304 + OFFLOAD(SIPV6_63_32, 32, U32_MAX, ip6.saddr.s6_addr32[2], 0, 2305 2305 src_ipv4_src_ipv6.ipv6_layout.ipv6[8]), 2306 - OFFLOAD(SIPV6_31_0, 4, ip6.saddr.s6_addr32[3], 0, 2306 + OFFLOAD(SIPV6_31_0, 32, U32_MAX, ip6.saddr.s6_addr32[3], 0, 2307 2307 src_ipv4_src_ipv6.ipv6_layout.ipv6[12]), 2308 - OFFLOAD(DIPV6_127_96, 4, ip6.daddr.s6_addr32[0], 0, 2308 + OFFLOAD(DIPV6_127_96, 32, U32_MAX, ip6.daddr.s6_addr32[0], 0, 2309 2309 dst_ipv4_dst_ipv6.ipv6_layout.ipv6[0]), 2310 - OFFLOAD(DIPV6_95_64, 4, ip6.daddr.s6_addr32[1], 0, 2310 + OFFLOAD(DIPV6_95_64, 32, U32_MAX, ip6.daddr.s6_addr32[1], 0, 2311 2311 dst_ipv4_dst_ipv6.ipv6_layout.ipv6[4]), 2312 - OFFLOAD(DIPV6_63_32, 4, ip6.daddr.s6_addr32[2], 0, 2312 + OFFLOAD(DIPV6_63_32, 32, U32_MAX, ip6.daddr.s6_addr32[2], 0, 2313 2313 dst_ipv4_dst_ipv6.ipv6_layout.ipv6[8]), 2314 - OFFLOAD(DIPV6_31_0, 4, ip6.daddr.s6_addr32[3], 0, 2314 + OFFLOAD(DIPV6_31_0, 32, U32_MAX, ip6.daddr.s6_addr32[3], 0, 2315 2315 dst_ipv4_dst_ipv6.ipv6_layout.ipv6[12]), 2316 - OFFLOAD(IPV6_HOPLIMIT, 1, ip6.hop_limit, 0, ttl_hoplimit), 2316 + OFFLOAD(IPV6_HOPLIMIT, 8, U8_MAX, ip6.hop_limit, 0, ttl_hoplimit), 2317 2317 2318 - OFFLOAD(TCP_SPORT, 2, tcp.source, 0, tcp_sport), 2319 - OFFLOAD(TCP_DPORT, 2, tcp.dest, 0, tcp_dport), 2320 - OFFLOAD(TCP_FLAGS, 1, tcp.ack_seq, 5, tcp_flags), 2318 + OFFLOAD(TCP_SPORT, 16, U16_MAX, tcp.source, 0, tcp_sport), 2319 + OFFLOAD(TCP_DPORT, 16, U16_MAX, tcp.dest, 0, tcp_dport), 2320 + /* in linux iphdr tcp_flags is 8 bits long */ 2321 + OFFLOAD(TCP_FLAGS, 8, U8_MAX, tcp.ack_seq, 5, tcp_flags), 2321 2322 2322 - OFFLOAD(UDP_SPORT, 2, udp.source, 0, udp_sport), 2323 - OFFLOAD(UDP_DPORT, 2, udp.dest, 0, udp_dport), 2323 + OFFLOAD(UDP_SPORT, 16, U16_MAX, udp.source, 0, udp_sport), 2324 + OFFLOAD(UDP_DPORT, 16, U16_MAX, udp.dest, 0, udp_dport), 2324 2325 }; 2325 2326 2326 2327 /* On input attr->max_mod_hdr_actions tells how many HW actions can be parsed at ··· 2335 2332 struct netlink_ext_ack *extack) 2336 2333 { 2337 2334 struct pedit_headers *set_masks, *add_masks, *set_vals, *add_vals; 2338 - void *headers_c = get_match_headers_criteria(*action_flags, 2339 - &parse_attr->spec); 2340 - void *headers_v = get_match_headers_value(*action_flags, 2341 - &parse_attr->spec); 2342 2335 int i, action_size, nactions, max_actions, first, last, next_z; 2343 - void *s_masks_p, *a_masks_p, *vals_p; 2336 + void *headers_c, *headers_v, *action, *vals_p; 2337 + u32 *s_masks_p, *a_masks_p, s_mask, a_mask; 2344 2338 struct mlx5_fields *f; 2345 - u8 cmd, field_bsize; 2346 - u32 s_mask, a_mask; 2347 2339 unsigned long mask; 2348 2340 __be32 mask_be32; 2349 2341 __be16 mask_be16; 2350 - void *action; 2342 + u8 cmd; 2343 + 2344 + headers_c = get_match_headers_criteria(*action_flags, &parse_attr->spec); 2345 + headers_v = get_match_headers_value(*action_flags, &parse_attr->spec); 2351 2346 2352 2347 set_masks = &hdrs[0].masks; 2353 2348 add_masks = &hdrs[1].masks; ··· 2370 2369 s_masks_p = (void *)set_masks + f->offset; 2371 2370 a_masks_p = (void *)add_masks + f->offset; 2372 2371 2373 - memcpy(&s_mask, s_masks_p, f->size); 2374 - memcpy(&a_mask, a_masks_p, f->size); 2372 + s_mask = *s_masks_p & f->field_mask; 2373 + a_mask = *a_masks_p & f->field_mask; 2375 2374 2376 2375 if (!s_mask && !a_mask) /* nothing to offload here */ 2377 2376 continue; ··· 2400 2399 vals_p = (void *)set_vals + f->offset; 2401 2400 /* don't rewrite if we have a match on the same value */ 2402 2401 if (cmp_val_mask(vals_p, s_masks_p, match_val, 2403 - match_mask, f->size)) 2402 + match_mask, f->field_bsize)) 2404 2403 skip = true; 2405 2404 /* clear to denote we consumed this field */ 2406 - memset(s_masks_p, 0, f->size); 2405 + *s_masks_p &= ~f->field_mask; 2407 2406 } else { 2408 - u32 zero = 0; 2409 - 2410 2407 cmd = MLX5_ACTION_TYPE_ADD; 2411 2408 mask = a_mask; 2412 2409 vals_p = (void *)add_vals + f->offset; 2413 2410 /* add 0 is no change */ 2414 - if (!memcmp(vals_p, &zero, f->size)) 2411 + if ((*(u32 *)vals_p & f->field_mask) == 0) 2415 2412 skip = true; 2416 2413 /* clear to denote we consumed this field */ 2417 - memset(a_masks_p, 0, f->size); 2414 + *a_masks_p &= ~f->field_mask; 2418 2415 } 2419 2416 if (skip) 2420 2417 continue; 2421 2418 2422 - field_bsize = f->size * BITS_PER_BYTE; 2423 - 2424 - if (field_bsize == 32) { 2419 + if (f->field_bsize == 32) { 2425 2420 mask_be32 = *(__be32 *)&mask; 2426 2421 mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32)); 2427 - } else if (field_bsize == 16) { 2422 + } else if (f->field_bsize == 16) { 2428 2423 mask_be16 = *(__be16 *)&mask; 2429 2424 mask = (__force unsigned long)cpu_to_le16(be16_to_cpu(mask_be16)); 2430 2425 } 2431 2426 2432 - first = find_first_bit(&mask, field_bsize); 2433 - next_z = find_next_zero_bit(&mask, field_bsize, first); 2434 - last = find_last_bit(&mask, field_bsize); 2427 + first = find_first_bit(&mask, f->field_bsize); 2428 + next_z = find_next_zero_bit(&mask, f->field_bsize, first); 2429 + last = find_last_bit(&mask, f->field_bsize); 2435 2430 if (first < next_z && next_z < last) { 2436 2431 NL_SET_ERR_MSG_MOD(extack, 2437 2432 "rewrite of few sub-fields isn't supported"); ··· 2440 2443 MLX5_SET(set_action_in, action, field, f->field); 2441 2444 2442 2445 if (cmd == MLX5_ACTION_TYPE_SET) { 2443 - MLX5_SET(set_action_in, action, offset, first); 2446 + int start; 2447 + 2448 + /* if field is bit sized it can start not from first bit */ 2449 + start = find_first_bit((unsigned long *)&f->field_mask, 2450 + f->field_bsize); 2451 + 2452 + MLX5_SET(set_action_in, action, offset, first - start); 2444 2453 /* length is num of bits to be written, zero means length of 32 */ 2445 2454 MLX5_SET(set_action_in, action, length, (last - first + 1)); 2446 2455 } 2447 2456 2448 - if (field_bsize == 32) 2457 + if (f->field_bsize == 32) 2449 2458 MLX5_SET(set_action_in, action, data, ntohl(*(__be32 *)vals_p) >> first); 2450 - else if (field_bsize == 16) 2459 + else if (f->field_bsize == 16) 2451 2460 MLX5_SET(set_action_in, action, data, ntohs(*(__be16 *)vals_p) >> first); 2452 - else if (field_bsize == 8) 2461 + else if (f->field_bsize == 8) 2453 2462 MLX5_SET(set_action_in, action, data, *(u8 *)vals_p >> first); 2454 2463 2455 2464 action += action_size; ··· 3444 3441 return -EOPNOTSUPP; 3445 3442 } 3446 3443 attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 3444 + } 3445 + 3446 + if (!(attr->action & 3447 + (MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) { 3448 + NL_SET_ERR_MSG(extack, "Rule must have at least one forward/drop action"); 3449 + return -EOPNOTSUPP; 3447 3450 } 3448 3451 3449 3452 if (attr->split_count > 0 && !mlx5_esw_has_fwd_fdb(priv->mdev)) {
+6
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
··· 461 461 if (unlikely(get_cqe_opcode(cqe) == MLX5_CQE_REQ_ERR)) { 462 462 if (!test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, 463 463 &sq->state)) { 464 + struct mlx5e_tx_wqe_info *wi; 465 + u16 ci; 466 + 467 + ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc); 468 + wi = &sq->db.wqe_info[ci]; 464 469 mlx5e_dump_error_cqe(sq, 465 470 (struct mlx5_err_cqe *)cqe); 471 + mlx5_wq_cyc_wqe_dump(&sq->wq, ci, wi->num_wqebbs); 466 472 queue_work(cq->channel->priv->wq, 467 473 &sq->recover_work); 468 474 }
+12 -1
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
··· 1831 1831 flush_workqueue(esw->work_queue); 1832 1832 } 1833 1833 1834 + static void mlx5_eswitch_clear_vf_vports_info(struct mlx5_eswitch *esw) 1835 + { 1836 + struct mlx5_vport *vport; 1837 + int i; 1838 + 1839 + mlx5_esw_for_each_vf_vport(esw, i, vport, esw->esw_funcs.num_vfs) 1840 + memset(&vport->info, 0, sizeof(vport->info)); 1841 + } 1842 + 1834 1843 /* Public E-Switch API */ 1835 1844 #define ESW_ALLOWED(esw) ((esw) && MLX5_ESWITCH_MANAGER((esw)->dev)) 1836 1845 ··· 1932 1923 return err; 1933 1924 } 1934 1925 1935 - void mlx5_eswitch_disable(struct mlx5_eswitch *esw) 1926 + void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf) 1936 1927 { 1937 1928 int old_mode; 1938 1929 ··· 1961 1952 mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB); 1962 1953 mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_ETH); 1963 1954 } 1955 + if (clear_vf) 1956 + mlx5_eswitch_clear_vf_vports_info(esw); 1964 1957 } 1965 1958 1966 1959 int mlx5_eswitch_init(struct mlx5_core_dev *dev)
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
··· 270 270 int mlx5_eswitch_init(struct mlx5_core_dev *dev); 271 271 void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw); 272 272 int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int mode); 273 - void mlx5_eswitch_disable(struct mlx5_eswitch *esw); 273 + void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf); 274 274 int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, 275 275 u16 vport, u8 mac[ETH_ALEN]); 276 276 int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, ··· 603 603 static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; } 604 604 static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {} 605 605 static inline int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int mode) { return 0; } 606 - static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw) {} 606 + static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf) {} 607 607 static inline bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1) { return true; } 608 608 static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev) { return false; } 609 609 static inline const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev)
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
··· 1369 1369 return -EINVAL; 1370 1370 } 1371 1371 1372 - mlx5_eswitch_disable(esw); 1372 + mlx5_eswitch_disable(esw, false); 1373 1373 mlx5_eswitch_update_num_of_vfs(esw, esw->dev->priv.sriov.num_vfs); 1374 1374 err = mlx5_eswitch_enable(esw, MLX5_ESWITCH_OFFLOADS); 1375 1375 if (err) { ··· 2195 2195 { 2196 2196 int err, err1; 2197 2197 2198 - mlx5_eswitch_disable(esw); 2198 + mlx5_eswitch_disable(esw, false); 2199 2199 err = mlx5_eswitch_enable(esw, MLX5_ESWITCH_LEGACY); 2200 2200 if (err) { 2201 2201 NL_SET_ERR_MSG_MOD(extack, "Failed setting eswitch to legacy");
+5 -5
drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.h
··· 35 35 36 36 #include <linux/mlx5/driver.h> 37 37 38 - enum mlx5_fpga_device_id { 39 - MLX5_FPGA_DEVICE_UNKNOWN = 0, 40 - MLX5_FPGA_DEVICE_KU040 = 1, 41 - MLX5_FPGA_DEVICE_KU060 = 2, 42 - MLX5_FPGA_DEVICE_KU060_2 = 3, 38 + enum mlx5_fpga_id { 39 + MLX5_FPGA_NEWTON = 0, 40 + MLX5_FPGA_EDISON = 1, 41 + MLX5_FPGA_MORSE = 2, 42 + MLX5_FPGA_MORSEQ = 3, 43 43 }; 44 44 45 45 enum mlx5_fpga_image {
+43 -22
drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c
··· 81 81 } 82 82 } 83 83 84 - static const char *mlx5_fpga_device_name(u32 device) 84 + static const char *mlx5_fpga_name(u32 fpga_id) 85 85 { 86 - switch (device) { 87 - case MLX5_FPGA_DEVICE_KU040: 88 - return "ku040"; 89 - case MLX5_FPGA_DEVICE_KU060: 90 - return "ku060"; 91 - case MLX5_FPGA_DEVICE_KU060_2: 92 - return "ku060_2"; 93 - case MLX5_FPGA_DEVICE_UNKNOWN: 94 - default: 95 - return "unknown"; 86 + static char ret[32]; 87 + 88 + switch (fpga_id) { 89 + case MLX5_FPGA_NEWTON: 90 + return "Newton"; 91 + case MLX5_FPGA_EDISON: 92 + return "Edison"; 93 + case MLX5_FPGA_MORSE: 94 + return "Morse"; 95 + case MLX5_FPGA_MORSEQ: 96 + return "MorseQ"; 96 97 } 98 + 99 + snprintf(ret, sizeof(ret), "Unknown %d", fpga_id); 100 + return ret; 101 + } 102 + 103 + static int mlx5_is_fpga_lookaside(u32 fpga_id) 104 + { 105 + return fpga_id != MLX5_FPGA_NEWTON && fpga_id != MLX5_FPGA_EDISON; 97 106 } 98 107 99 108 static int mlx5_fpga_device_load_check(struct mlx5_fpga_device *fdev) ··· 119 110 fdev->last_admin_image = query.admin_image; 120 111 fdev->last_oper_image = query.oper_image; 121 112 122 - mlx5_fpga_dbg(fdev, "Status %u; Admin image %u; Oper image %u\n", 123 - query.status, query.admin_image, query.oper_image); 113 + mlx5_fpga_info(fdev, "Status %u; Admin image %u; Oper image %u\n", 114 + query.status, query.admin_image, query.oper_image); 115 + 116 + /* for FPGA lookaside projects FPGA load status is not important */ 117 + if (mlx5_is_fpga_lookaside(MLX5_CAP_FPGA(fdev->mdev, fpga_id))) 118 + return 0; 124 119 125 120 if (query.status != MLX5_FPGA_STATUS_SUCCESS) { 126 121 mlx5_fpga_err(fdev, "%s image failed to load; status %u\n", ··· 180 167 struct mlx5_fpga_device *fdev = mdev->fpga; 181 168 unsigned int max_num_qps; 182 169 unsigned long flags; 183 - u32 fpga_device_id; 170 + u32 fpga_id; 184 171 int err; 185 172 186 173 if (!fdev) 187 174 return 0; 188 175 189 - err = mlx5_fpga_device_load_check(fdev); 190 - if (err) 191 - goto out; 192 - 193 176 err = mlx5_fpga_caps(fdev->mdev); 194 177 if (err) 195 178 goto out; 196 179 197 - fpga_device_id = MLX5_CAP_FPGA(fdev->mdev, fpga_device); 198 - mlx5_fpga_info(fdev, "%s:%u; %s image, version %u; SBU %06x:%04x version %d\n", 199 - mlx5_fpga_device_name(fpga_device_id), 200 - fpga_device_id, 180 + err = mlx5_fpga_device_load_check(fdev); 181 + if (err) 182 + goto out; 183 + 184 + fpga_id = MLX5_CAP_FPGA(fdev->mdev, fpga_id); 185 + mlx5_fpga_info(fdev, "FPGA card %s:%u\n", mlx5_fpga_name(fpga_id), fpga_id); 186 + 187 + /* No QPs if FPGA does not participate in net processing */ 188 + if (mlx5_is_fpga_lookaside(fpga_id)) 189 + goto out; 190 + 191 + mlx5_fpga_info(fdev, "%s(%d): image, version %u; SBU %06x:%04x version %d\n", 201 192 mlx5_fpga_image_name(fdev->last_oper_image), 193 + fdev->last_oper_image, 202 194 MLX5_CAP_FPGA(fdev->mdev, image_version), 203 195 MLX5_CAP_FPGA(fdev->mdev, ieee_vendor_id), 204 196 MLX5_CAP_FPGA(fdev->mdev, sandbox_product_id), ··· 280 262 int err; 281 263 282 264 if (!fdev) 265 + return; 266 + 267 + if (mlx5_is_fpga_lookaside(MLX5_CAP_FPGA(fdev->mdev, fpga_id))) 283 268 return; 284 269 285 270 spin_lock_irqsave(&fdev->state_lock, flags);
+65 -24
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
··· 531 531 } 532 532 } 533 533 534 + static void del_sw_fte_rcu(struct rcu_head *head) 535 + { 536 + struct fs_fte *fte = container_of(head, struct fs_fte, rcu); 537 + struct mlx5_flow_steering *steering = get_steering(&fte->node); 538 + 539 + kmem_cache_free(steering->ftes_cache, fte); 540 + } 541 + 534 542 static void del_sw_fte(struct fs_node *node) 535 543 { 536 - struct mlx5_flow_steering *steering = get_steering(node); 537 544 struct mlx5_flow_group *fg; 538 545 struct fs_fte *fte; 539 546 int err; ··· 553 546 rhash_fte); 554 547 WARN_ON(err); 555 548 ida_simple_remove(&fg->fte_allocator, fte->index - fg->start_index); 556 - kmem_cache_free(steering->ftes_cache, fte); 549 + 550 + call_rcu(&fte->rcu, del_sw_fte_rcu); 557 551 } 558 552 559 553 static void del_hw_flow_group(struct fs_node *node) ··· 1631 1623 } 1632 1624 1633 1625 static struct fs_fte * 1634 - lookup_fte_locked(struct mlx5_flow_group *g, 1635 - const u32 *match_value, 1636 - bool take_write) 1626 + lookup_fte_for_write_locked(struct mlx5_flow_group *g, const u32 *match_value) 1637 1627 { 1638 1628 struct fs_fte *fte_tmp; 1639 1629 1640 - if (take_write) 1641 - nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); 1642 - else 1643 - nested_down_read_ref_node(&g->node, FS_LOCK_PARENT); 1644 - fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value, 1645 - rhash_fte); 1630 + nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); 1631 + 1632 + fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value, rhash_fte); 1646 1633 if (!fte_tmp || !tree_get_node(&fte_tmp->node)) { 1647 1634 fte_tmp = NULL; 1648 1635 goto out; 1649 1636 } 1637 + 1638 + if (!fte_tmp->node.active) { 1639 + tree_put_node(&fte_tmp->node, false); 1640 + fte_tmp = NULL; 1641 + goto out; 1642 + } 1643 + nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); 1644 + 1645 + out: 1646 + up_write_ref_node(&g->node, false); 1647 + return fte_tmp; 1648 + } 1649 + 1650 + static struct fs_fte * 1651 + lookup_fte_for_read_locked(struct mlx5_flow_group *g, const u32 *match_value) 1652 + { 1653 + struct fs_fte *fte_tmp; 1654 + 1655 + if (!tree_get_node(&g->node)) 1656 + return NULL; 1657 + 1658 + rcu_read_lock(); 1659 + fte_tmp = rhashtable_lookup(&g->ftes_hash, match_value, rhash_fte); 1660 + if (!fte_tmp || !tree_get_node(&fte_tmp->node)) { 1661 + rcu_read_unlock(); 1662 + fte_tmp = NULL; 1663 + goto out; 1664 + } 1665 + rcu_read_unlock(); 1666 + 1650 1667 if (!fte_tmp->node.active) { 1651 1668 tree_put_node(&fte_tmp->node, false); 1652 1669 fte_tmp = NULL; ··· 1679 1646 } 1680 1647 1681 1648 nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); 1649 + 1682 1650 out: 1683 - if (take_write) 1684 - up_write_ref_node(&g->node, false); 1685 - else 1686 - up_read_ref_node(&g->node); 1651 + tree_put_node(&g->node, false); 1687 1652 return fte_tmp; 1653 + } 1654 + 1655 + static struct fs_fte * 1656 + lookup_fte_locked(struct mlx5_flow_group *g, const u32 *match_value, bool write) 1657 + { 1658 + if (write) 1659 + return lookup_fte_for_write_locked(g, match_value); 1660 + else 1661 + return lookup_fte_for_read_locked(g, match_value); 1688 1662 } 1689 1663 1690 1664 static struct mlx5_flow_handle * ··· 1854 1814 return rule; 1855 1815 } 1856 1816 1817 + fte = alloc_fte(ft, spec, flow_act); 1818 + if (IS_ERR(fte)) { 1819 + up_write_ref_node(&ft->node, false); 1820 + err = PTR_ERR(fte); 1821 + goto err_alloc_fte; 1822 + } 1823 + 1857 1824 nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); 1858 1825 up_write_ref_node(&ft->node, false); 1859 1826 ··· 1868 1821 if (err) 1869 1822 goto err_release_fg; 1870 1823 1871 - fte = alloc_fte(ft, spec, flow_act); 1872 - if (IS_ERR(fte)) { 1873 - err = PTR_ERR(fte); 1874 - goto err_release_fg; 1875 - } 1876 - 1877 1824 err = insert_fte(g, fte); 1878 - if (err) { 1879 - kmem_cache_free(steering->ftes_cache, fte); 1825 + if (err) 1880 1826 goto err_release_fg; 1881 - } 1882 1827 1883 1828 nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD); 1884 1829 up_write_ref_node(&g->node, false); ··· 1882 1843 1883 1844 err_release_fg: 1884 1845 up_write_ref_node(&g->node, false); 1846 + kmem_cache_free(steering->ftes_cache, fte); 1847 + err_alloc_fte: 1885 1848 tree_put_node(&g->node, false); 1886 1849 return ERR_PTR(err); 1887 1850 }
+1
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
··· 202 202 enum fs_fte_status status; 203 203 struct mlx5_fc *counter; 204 204 struct rhash_head hash; 205 + struct rcu_head rcu; 205 206 int modify_mask; 206 207 }; 207 208
+35 -30
drivers/net/ethernet/mellanox/mlx5/core/lag.c
··· 145 145 { 146 146 *port1 = 1; 147 147 *port2 = 2; 148 - if (!tracker->netdev_state[0].tx_enabled || 149 - !tracker->netdev_state[0].link_up) { 148 + if (!tracker->netdev_state[MLX5_LAG_P1].tx_enabled || 149 + !tracker->netdev_state[MLX5_LAG_P1].link_up) { 150 150 *port1 = 2; 151 151 return; 152 152 } 153 153 154 - if (!tracker->netdev_state[1].tx_enabled || 155 - !tracker->netdev_state[1].link_up) 154 + if (!tracker->netdev_state[MLX5_LAG_P2].tx_enabled || 155 + !tracker->netdev_state[MLX5_LAG_P2].link_up) 156 156 *port2 = 1; 157 157 } 158 158 159 159 void mlx5_modify_lag(struct mlx5_lag *ldev, 160 160 struct lag_tracker *tracker) 161 161 { 162 - struct mlx5_core_dev *dev0 = ldev->pf[0].dev; 162 + struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; 163 163 u8 v2p_port1, v2p_port2; 164 164 int err; 165 165 166 166 mlx5_infer_tx_affinity_mapping(tracker, &v2p_port1, 167 167 &v2p_port2); 168 168 169 - if (v2p_port1 != ldev->v2p_map[0] || 170 - v2p_port2 != ldev->v2p_map[1]) { 171 - ldev->v2p_map[0] = v2p_port1; 172 - ldev->v2p_map[1] = v2p_port2; 169 + if (v2p_port1 != ldev->v2p_map[MLX5_LAG_P1] || 170 + v2p_port2 != ldev->v2p_map[MLX5_LAG_P2]) { 171 + ldev->v2p_map[MLX5_LAG_P1] = v2p_port1; 172 + ldev->v2p_map[MLX5_LAG_P2] = v2p_port2; 173 173 174 174 mlx5_core_info(dev0, "modify lag map port 1:%d port 2:%d", 175 - ldev->v2p_map[0], ldev->v2p_map[1]); 175 + ldev->v2p_map[MLX5_LAG_P1], 176 + ldev->v2p_map[MLX5_LAG_P2]); 176 177 177 178 err = mlx5_cmd_modify_lag(dev0, v2p_port1, v2p_port2); 178 179 if (err) ··· 186 185 static int mlx5_create_lag(struct mlx5_lag *ldev, 187 186 struct lag_tracker *tracker) 188 187 { 189 - struct mlx5_core_dev *dev0 = ldev->pf[0].dev; 188 + struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; 190 189 int err; 191 190 192 - mlx5_infer_tx_affinity_mapping(tracker, &ldev->v2p_map[0], 193 - &ldev->v2p_map[1]); 191 + mlx5_infer_tx_affinity_mapping(tracker, &ldev->v2p_map[MLX5_LAG_P1], 192 + &ldev->v2p_map[MLX5_LAG_P2]); 194 193 195 194 mlx5_core_info(dev0, "lag map port 1:%d port 2:%d", 196 - ldev->v2p_map[0], ldev->v2p_map[1]); 195 + ldev->v2p_map[MLX5_LAG_P1], ldev->v2p_map[MLX5_LAG_P2]); 197 196 198 - err = mlx5_cmd_create_lag(dev0, ldev->v2p_map[0], ldev->v2p_map[1]); 197 + err = mlx5_cmd_create_lag(dev0, ldev->v2p_map[MLX5_LAG_P1], 198 + ldev->v2p_map[MLX5_LAG_P2]); 199 199 if (err) 200 200 mlx5_core_err(dev0, 201 201 "Failed to create LAG (%d)\n", ··· 209 207 u8 flags) 210 208 { 211 209 bool roce_lag = !!(flags & MLX5_LAG_FLAG_ROCE); 212 - struct mlx5_core_dev *dev0 = ldev->pf[0].dev; 210 + struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; 213 211 int err; 214 212 215 213 err = mlx5_create_lag(ldev, tracker); ··· 231 229 232 230 static int mlx5_deactivate_lag(struct mlx5_lag *ldev) 233 231 { 234 - struct mlx5_core_dev *dev0 = ldev->pf[0].dev; 232 + struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; 235 233 bool roce_lag = __mlx5_lag_is_roce(ldev); 236 234 int err; 237 235 ··· 254 252 255 253 static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev) 256 254 { 257 - if (!ldev->pf[0].dev || !ldev->pf[1].dev) 255 + if (!ldev->pf[MLX5_LAG_P1].dev || !ldev->pf[MLX5_LAG_P2].dev) 258 256 return false; 259 257 260 258 #ifdef CONFIG_MLX5_ESWITCH 261 - return mlx5_esw_lag_prereq(ldev->pf[0].dev, ldev->pf[1].dev); 259 + return mlx5_esw_lag_prereq(ldev->pf[MLX5_LAG_P1].dev, 260 + ldev->pf[MLX5_LAG_P2].dev); 262 261 #else 263 - return (!mlx5_sriov_is_enabled(ldev->pf[0].dev) && 264 - !mlx5_sriov_is_enabled(ldev->pf[1].dev)); 262 + return (!mlx5_sriov_is_enabled(ldev->pf[MLX5_LAG_P1].dev) && 263 + !mlx5_sriov_is_enabled(ldev->pf[MLX5_LAG_P2].dev)); 265 264 #endif 266 265 } 267 266 ··· 288 285 289 286 static void mlx5_do_bond(struct mlx5_lag *ldev) 290 287 { 291 - struct mlx5_core_dev *dev0 = ldev->pf[0].dev; 292 - struct mlx5_core_dev *dev1 = ldev->pf[1].dev; 288 + struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; 289 + struct mlx5_core_dev *dev1 = ldev->pf[MLX5_LAG_P2].dev; 293 290 struct lag_tracker tracker; 294 291 bool do_bond, roce_lag; 295 292 int err; ··· 695 692 goto unlock; 696 693 697 694 if (ldev->tracker.tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) { 698 - ndev = ldev->tracker.netdev_state[0].tx_enabled ? 699 - ldev->pf[0].netdev : ldev->pf[1].netdev; 695 + ndev = ldev->tracker.netdev_state[MLX5_LAG_P1].tx_enabled ? 696 + ldev->pf[MLX5_LAG_P1].netdev : 697 + ldev->pf[MLX5_LAG_P2].netdev; 700 698 } else { 701 - ndev = ldev->pf[0].netdev; 699 + ndev = ldev->pf[MLX5_LAG_P1].netdev; 702 700 } 703 701 if (ndev) 704 702 dev_hold(ndev); ··· 721 717 return true; 722 718 723 719 ldev = mlx5_lag_dev_get(dev); 724 - if (!ldev || !__mlx5_lag_is_roce(ldev) || ldev->pf[0].dev == dev) 720 + if (!ldev || !__mlx5_lag_is_roce(ldev) || 721 + ldev->pf[MLX5_LAG_P1].dev == dev) 725 722 return true; 726 723 727 724 /* If bonded, we do not add an IB device for PF1. */ ··· 751 746 ldev = mlx5_lag_dev_get(dev); 752 747 if (ldev && __mlx5_lag_is_roce(ldev)) { 753 748 num_ports = MLX5_MAX_PORTS; 754 - mdev[0] = ldev->pf[0].dev; 755 - mdev[1] = ldev->pf[1].dev; 749 + mdev[MLX5_LAG_P1] = ldev->pf[MLX5_LAG_P1].dev; 750 + mdev[MLX5_LAG_P2] = ldev->pf[MLX5_LAG_P2].dev; 756 751 } else { 757 752 num_ports = 1; 758 - mdev[0] = dev; 753 + mdev[MLX5_LAG_P1] = dev; 759 754 } 760 755 761 756 for (i = 0; i < num_ports; ++i) {
+5
drivers/net/ethernet/mellanox/mlx5/core/lag.h
··· 8 8 #include "lag_mp.h" 9 9 10 10 enum { 11 + MLX5_LAG_P1, 12 + MLX5_LAG_P2, 13 + }; 14 + 15 + enum { 11 16 MLX5_LAG_FLAG_ROCE = 1 << 0, 12 17 MLX5_LAG_FLAG_SRIOV = 1 << 1, 13 18 MLX5_LAG_FLAG_MULTIPATH = 1 << 2,
+36 -33
drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c
··· 11 11 12 12 static bool mlx5_lag_multipath_check_prereq(struct mlx5_lag *ldev) 13 13 { 14 - if (!ldev->pf[0].dev || !ldev->pf[1].dev) 14 + if (!ldev->pf[MLX5_LAG_P1].dev || !ldev->pf[MLX5_LAG_P2].dev) 15 15 return false; 16 16 17 - return mlx5_esw_multipath_prereq(ldev->pf[0].dev, ldev->pf[1].dev); 17 + return mlx5_esw_multipath_prereq(ldev->pf[MLX5_LAG_P1].dev, 18 + ldev->pf[MLX5_LAG_P2].dev); 18 19 } 19 20 20 21 static bool __mlx5_lag_is_multipath(struct mlx5_lag *ldev) ··· 44 43 * 2 - set affinity to port 2. 45 44 * 46 45 **/ 47 - static void mlx5_lag_set_port_affinity(struct mlx5_lag *ldev, int port) 46 + static void mlx5_lag_set_port_affinity(struct mlx5_lag *ldev, 47 + enum mlx5_lag_port_affinity port) 48 48 { 49 49 struct lag_tracker tracker; 50 50 ··· 53 51 return; 54 52 55 53 switch (port) { 56 - case 0: 57 - tracker.netdev_state[0].tx_enabled = true; 58 - tracker.netdev_state[1].tx_enabled = true; 59 - tracker.netdev_state[0].link_up = true; 60 - tracker.netdev_state[1].link_up = true; 54 + case MLX5_LAG_NORMAL_AFFINITY: 55 + tracker.netdev_state[MLX5_LAG_P1].tx_enabled = true; 56 + tracker.netdev_state[MLX5_LAG_P2].tx_enabled = true; 57 + tracker.netdev_state[MLX5_LAG_P1].link_up = true; 58 + tracker.netdev_state[MLX5_LAG_P2].link_up = true; 61 59 break; 62 - case 1: 63 - tracker.netdev_state[0].tx_enabled = true; 64 - tracker.netdev_state[0].link_up = true; 65 - tracker.netdev_state[1].tx_enabled = false; 66 - tracker.netdev_state[1].link_up = false; 60 + case MLX5_LAG_P1_AFFINITY: 61 + tracker.netdev_state[MLX5_LAG_P1].tx_enabled = true; 62 + tracker.netdev_state[MLX5_LAG_P1].link_up = true; 63 + tracker.netdev_state[MLX5_LAG_P2].tx_enabled = false; 64 + tracker.netdev_state[MLX5_LAG_P2].link_up = false; 67 65 break; 68 - case 2: 69 - tracker.netdev_state[0].tx_enabled = false; 70 - tracker.netdev_state[0].link_up = false; 71 - tracker.netdev_state[1].tx_enabled = true; 72 - tracker.netdev_state[1].link_up = true; 66 + case MLX5_LAG_P2_AFFINITY: 67 + tracker.netdev_state[MLX5_LAG_P1].tx_enabled = false; 68 + tracker.netdev_state[MLX5_LAG_P1].link_up = false; 69 + tracker.netdev_state[MLX5_LAG_P2].tx_enabled = true; 70 + tracker.netdev_state[MLX5_LAG_P2].link_up = true; 73 71 break; 74 72 default: 75 - mlx5_core_warn(ldev->pf[0].dev, "Invalid affinity port %d", 76 - port); 73 + mlx5_core_warn(ldev->pf[MLX5_LAG_P1].dev, 74 + "Invalid affinity port %d", port); 77 75 return; 78 76 } 79 77 80 - if (tracker.netdev_state[0].tx_enabled) 81 - mlx5_notifier_call_chain(ldev->pf[0].dev->priv.events, 78 + if (tracker.netdev_state[MLX5_LAG_P1].tx_enabled) 79 + mlx5_notifier_call_chain(ldev->pf[MLX5_LAG_P1].dev->priv.events, 82 80 MLX5_DEV_EVENT_PORT_AFFINITY, 83 81 (void *)0); 84 82 85 - if (tracker.netdev_state[1].tx_enabled) 86 - mlx5_notifier_call_chain(ldev->pf[1].dev->priv.events, 83 + if (tracker.netdev_state[MLX5_LAG_P2].tx_enabled) 84 + mlx5_notifier_call_chain(ldev->pf[MLX5_LAG_P2].dev->priv.events, 87 85 MLX5_DEV_EVENT_PORT_AFFINITY, 88 86 (void *)0); 89 87 ··· 143 141 /* Verify next hops are ports of the same hca */ 144 142 fib_nh0 = fib_info_nh(fi, 0); 145 143 fib_nh1 = fib_info_nh(fi, 1); 146 - if (!(fib_nh0->fib_nh_dev == ldev->pf[0].netdev && 147 - fib_nh1->fib_nh_dev == ldev->pf[1].netdev) && 148 - !(fib_nh0->fib_nh_dev == ldev->pf[1].netdev && 149 - fib_nh1->fib_nh_dev == ldev->pf[0].netdev)) { 150 - mlx5_core_warn(ldev->pf[0].dev, "Multipath offload require two ports of the same HCA\n"); 144 + if (!(fib_nh0->fib_nh_dev == ldev->pf[MLX5_LAG_P1].netdev && 145 + fib_nh1->fib_nh_dev == ldev->pf[MLX5_LAG_P2].netdev) && 146 + !(fib_nh0->fib_nh_dev == ldev->pf[MLX5_LAG_P2].netdev && 147 + fib_nh1->fib_nh_dev == ldev->pf[MLX5_LAG_P1].netdev)) { 148 + mlx5_core_warn(ldev->pf[MLX5_LAG_P1].dev, 149 + "Multipath offload require two ports of the same HCA\n"); 151 150 return; 152 151 } 153 152 ··· 160 157 mlx5_activate_lag(ldev, &tracker, MLX5_LAG_FLAG_MULTIPATH); 161 158 } 162 159 163 - mlx5_lag_set_port_affinity(ldev, 0); 160 + mlx5_lag_set_port_affinity(ldev, MLX5_LAG_NORMAL_AFFINITY); 164 161 mp->mfi = fi; 165 162 } 166 163 ··· 185 182 } 186 183 } else if (event == FIB_EVENT_NH_ADD && 187 184 fib_info_num_path(fi) == 2) { 188 - mlx5_lag_set_port_affinity(ldev, 0); 185 + mlx5_lag_set_port_affinity(ldev, MLX5_LAG_NORMAL_AFFINITY); 189 186 } 190 187 } 191 188 ··· 270 267 return notifier_from_errno(-EINVAL); 271 268 } 272 269 fib_dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev; 273 - if (fib_dev != ldev->pf[0].netdev && 274 - fib_dev != ldev->pf[1].netdev) { 270 + if (fib_dev != ldev->pf[MLX5_LAG_P1].netdev && 271 + fib_dev != ldev->pf[MLX5_LAG_P2].netdev) { 275 272 return NOTIFY_DONE; 276 273 } 277 274 fib_work = mlx5_lag_init_fib_work(ldev, event);
+6
drivers/net/ethernet/mellanox/mlx5/core/lag_mp.h
··· 7 7 #include "lag.h" 8 8 #include "mlx5_core.h" 9 9 10 + enum mlx5_lag_port_affinity { 11 + MLX5_LAG_NORMAL_AFFINITY, 12 + MLX5_LAG_P1_AFFINITY, 13 + MLX5_LAG_P2_AFFINITY, 14 + }; 15 + 10 16 struct lag_mp { 11 17 struct notifier_block fib_nb; 12 18 struct fib_info *mfi; /* used in tracking fib events */
+1 -3
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 1228 1228 1229 1229 static int mlx5_unload_one(struct mlx5_core_dev *dev, bool cleanup) 1230 1230 { 1231 - int err = 0; 1232 - 1233 1231 if (cleanup) { 1234 1232 mlx5_unregister_device(dev); 1235 1233 mlx5_drain_health_wq(dev); ··· 1255 1257 mlx5_function_teardown(dev, cleanup); 1256 1258 out: 1257 1259 mutex_unlock(&dev->intf_state_mutex); 1258 - return err; 1260 + return 0; 1259 1261 } 1260 1262 1261 1263 static int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx)
+5 -5
drivers/net/ethernet/mellanox/mlx5/core/sriov.c
··· 108 108 return 0; 109 109 } 110 110 111 - static void mlx5_device_disable_sriov(struct mlx5_core_dev *dev) 111 + static void mlx5_device_disable_sriov(struct mlx5_core_dev *dev, bool clear_vf) 112 112 { 113 113 struct mlx5_core_sriov *sriov = &dev->priv.sriov; 114 114 int num_vfs = pci_num_vf(dev->pdev); ··· 127 127 } 128 128 129 129 if (MLX5_ESWITCH_MANAGER(dev)) 130 - mlx5_eswitch_disable(dev->priv.eswitch); 130 + mlx5_eswitch_disable(dev->priv.eswitch, clear_vf); 131 131 132 132 if (mlx5_wait_for_pages(dev, &dev->priv.vfs_pages)) 133 133 mlx5_core_warn(dev, "timeout reclaiming VFs pages\n"); ··· 147 147 err = pci_enable_sriov(pdev, num_vfs); 148 148 if (err) { 149 149 mlx5_core_warn(dev, "pci_enable_sriov failed : %d\n", err); 150 - mlx5_device_disable_sriov(dev); 150 + mlx5_device_disable_sriov(dev, true); 151 151 } 152 152 return err; 153 153 } ··· 157 157 struct mlx5_core_dev *dev = pci_get_drvdata(pdev); 158 158 159 159 pci_disable_sriov(pdev); 160 - mlx5_device_disable_sriov(dev); 160 + mlx5_device_disable_sriov(dev, true); 161 161 } 162 162 163 163 int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs) ··· 192 192 if (!mlx5_core_is_pf(dev)) 193 193 return; 194 194 195 - mlx5_device_disable_sriov(dev); 195 + mlx5_device_disable_sriov(dev, false); 196 196 } 197 197 198 198 static u16 mlx5_get_max_vfs(struct mlx5_core_dev *dev)
-98
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_crc32.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 - /* Copyright (c) 2019 Mellanox Technologies. */ 3 - 4 - /* Copyright (c) 2011-2015 Stephan Brumme. All rights reserved. 5 - * Slicing-by-16 contributed by Bulat Ziganshin 6 - * 7 - * This software is provided 'as-is', without any express or implied warranty. 8 - * In no event will the author be held liable for any damages arising from the 9 - * of this software. 10 - * 11 - * Permission is granted to anyone to use this software for any purpose, 12 - * including commercial applications, and to alter it and redistribute it 13 - * freely, subject to the following restrictions: 14 - * 15 - * 1. The origin of this software must not be misrepresented; you must not 16 - * claim that you wrote the original software. 17 - * 2. If you use this software in a product, an acknowledgment in the product 18 - * documentation would be appreciated but is not required. 19 - * 3. Altered source versions must be plainly marked as such, and must not be 20 - * misrepresented as being the original software. 21 - * 22 - * Taken from http://create.stephan-brumme.com/crc32/ and adapted. 23 - */ 24 - 25 - #include "dr_types.h" 26 - 27 - #define DR_STE_CRC_POLY 0xEDB88320L 28 - 29 - static u32 dr_ste_crc_tab32[8][256]; 30 - 31 - static void dr_crc32_calc_lookup_entry(u32 (*tbl)[256], u8 i, u8 j) 32 - { 33 - tbl[i][j] = (tbl[i - 1][j] >> 8) ^ tbl[0][tbl[i - 1][j] & 0xff]; 34 - } 35 - 36 - void mlx5dr_crc32_init_table(void) 37 - { 38 - u32 crc, i, j; 39 - 40 - for (i = 0; i < 256; i++) { 41 - crc = i; 42 - for (j = 0; j < 8; j++) { 43 - if (crc & 0x00000001L) 44 - crc = (crc >> 1) ^ DR_STE_CRC_POLY; 45 - else 46 - crc = crc >> 1; 47 - } 48 - dr_ste_crc_tab32[0][i] = crc; 49 - } 50 - 51 - /* Init CRC lookup tables according to crc_slice_8 algorithm */ 52 - for (i = 0; i < 256; i++) { 53 - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 1, i); 54 - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 2, i); 55 - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 3, i); 56 - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 4, i); 57 - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 5, i); 58 - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 6, i); 59 - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 7, i); 60 - } 61 - } 62 - 63 - /* Compute CRC32 (Slicing-by-8 algorithm) */ 64 - u32 mlx5dr_crc32_slice8_calc(const void *input_data, size_t length) 65 - { 66 - const u32 *curr = (const u32 *)input_data; 67 - const u8 *curr_char; 68 - u32 crc = 0, one, two; 69 - 70 - if (!input_data) 71 - return 0; 72 - 73 - /* Process eight bytes at once (Slicing-by-8) */ 74 - while (length >= 8) { 75 - one = *curr++ ^ crc; 76 - two = *curr++; 77 - 78 - crc = dr_ste_crc_tab32[0][(two >> 24) & 0xff] 79 - ^ dr_ste_crc_tab32[1][(two >> 16) & 0xff] 80 - ^ dr_ste_crc_tab32[2][(two >> 8) & 0xff] 81 - ^ dr_ste_crc_tab32[3][two & 0xff] 82 - ^ dr_ste_crc_tab32[4][(one >> 24) & 0xff] 83 - ^ dr_ste_crc_tab32[5][(one >> 16) & 0xff] 84 - ^ dr_ste_crc_tab32[6][(one >> 8) & 0xff] 85 - ^ dr_ste_crc_tab32[7][one & 0xff]; 86 - 87 - length -= 8; 88 - } 89 - 90 - curr_char = (const u8 *)curr; 91 - /* Remaining 1 to 7 bytes (standard algorithm) */ 92 - while (length-- != 0) 93 - crc = (crc >> 8) ^ dr_ste_crc_tab32[0][(crc & 0xff) 94 - ^ *curr_char++]; 95 - 96 - return ((crc >> 24) & 0xff) | ((crc << 8) & 0xff0000) | 97 - ((crc >> 8) & 0xff00) | ((crc << 24) & 0xff000000); 98 - }
-3
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c
··· 326 326 goto uninit_resourses; 327 327 } 328 328 329 - /* Init CRC table for htbl CRC calculation */ 330 - mlx5dr_crc32_init_table(); 331 - 332 329 return dmn; 333 330 334 331 uninit_resourses:
+33 -32
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c
··· 146 146 147 147 int mlx5dr_matcher_select_builders(struct mlx5dr_matcher *matcher, 148 148 struct mlx5dr_matcher_rx_tx *nic_matcher, 149 - bool ipv6) 149 + enum mlx5dr_ipv outer_ipv, 150 + enum mlx5dr_ipv inner_ipv) 150 151 { 151 - if (ipv6) { 152 - nic_matcher->ste_builder = nic_matcher->ste_builder6; 153 - nic_matcher->num_of_builders = nic_matcher->num_of_builders6; 154 - } else { 155 - nic_matcher->ste_builder = nic_matcher->ste_builder4; 156 - nic_matcher->num_of_builders = nic_matcher->num_of_builders4; 157 - } 152 + nic_matcher->ste_builder = 153 + nic_matcher->ste_builder_arr[outer_ipv][inner_ipv]; 154 + nic_matcher->num_of_builders = 155 + nic_matcher->num_of_builders_arr[outer_ipv][inner_ipv]; 158 156 159 - if (!nic_matcher->num_of_builders) { 157 + if (!nic_matcher->ste_builder) { 160 158 mlx5dr_dbg(matcher->tbl->dmn, 161 159 "Rule not supported on this matcher due to IP related fields\n"); 162 160 return -EINVAL; ··· 165 167 166 168 static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, 167 169 struct mlx5dr_matcher_rx_tx *nic_matcher, 168 - bool ipv6) 170 + enum mlx5dr_ipv outer_ipv, 171 + enum mlx5dr_ipv inner_ipv) 169 172 { 170 173 struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn; 171 174 struct mlx5dr_domain *dmn = matcher->tbl->dmn; 172 175 struct mlx5dr_match_param mask = {}; 173 176 struct mlx5dr_match_misc3 *misc3; 174 177 struct mlx5dr_ste_build *sb; 175 - u8 *num_of_builders; 176 178 bool inner, rx; 177 179 int idx = 0; 178 180 int ret, i; 179 181 180 - if (ipv6) { 181 - sb = nic_matcher->ste_builder6; 182 - num_of_builders = &nic_matcher->num_of_builders6; 183 - } else { 184 - sb = nic_matcher->ste_builder4; 185 - num_of_builders = &nic_matcher->num_of_builders4; 186 - } 187 - 182 + sb = nic_matcher->ste_builder_arr[outer_ipv][inner_ipv]; 188 183 rx = nic_dmn->ste_type == MLX5DR_STE_TYPE_RX; 189 184 190 185 /* Create a temporary mask to track and clear used mask fields */ ··· 240 249 if (DR_MASK_IS_L2_DST(mask.outer, mask.misc, outer)) 241 250 mlx5dr_ste_build_eth_l2_dst(&sb[idx++], &mask, inner, rx); 242 251 243 - if (ipv6) { 252 + if (outer_ipv == DR_RULE_IPV6) { 244 253 if (dr_mask_is_dst_addr_set(&mask.outer)) 245 254 mlx5dr_ste_build_eth_l3_ipv6_dst(&sb[idx++], &mask, 246 255 inner, rx); ··· 316 325 if (DR_MASK_IS_L2_DST(mask.inner, mask.misc, inner)) 317 326 mlx5dr_ste_build_eth_l2_dst(&sb[idx++], &mask, inner, rx); 318 327 319 - if (ipv6) { 328 + if (inner_ipv == DR_RULE_IPV6) { 320 329 if (dr_mask_is_dst_addr_set(&mask.inner)) 321 330 mlx5dr_ste_build_eth_l3_ipv6_dst(&sb[idx++], &mask, 322 331 inner, rx); ··· 364 373 } 365 374 } 366 375 367 - *num_of_builders = idx; 376 + nic_matcher->ste_builder = sb; 377 + nic_matcher->num_of_builders_arr[outer_ipv][inner_ipv] = idx; 368 378 369 379 return 0; 370 380 } ··· 516 524 } 517 525 } 518 526 519 - static int dr_matcher_init_nic(struct mlx5dr_matcher *matcher, 520 - struct mlx5dr_matcher_rx_tx *nic_matcher) 527 + static int dr_matcher_set_all_ste_builders(struct mlx5dr_matcher *matcher, 528 + struct mlx5dr_matcher_rx_tx *nic_matcher) 521 529 { 522 530 struct mlx5dr_domain *dmn = matcher->tbl->dmn; 523 - int ret, ret_v4, ret_v6; 524 531 525 - ret_v4 = dr_matcher_set_ste_builders(matcher, nic_matcher, false); 526 - ret_v6 = dr_matcher_set_ste_builders(matcher, nic_matcher, true); 532 + dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV4, DR_RULE_IPV4); 533 + dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV4, DR_RULE_IPV6); 534 + dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV6, DR_RULE_IPV4); 535 + dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV6, DR_RULE_IPV6); 527 536 528 - if (ret_v4 && ret_v6) { 537 + if (!nic_matcher->ste_builder) { 529 538 mlx5dr_dbg(dmn, "Cannot generate IPv4 or IPv6 rules with given mask\n"); 530 539 return -EINVAL; 531 540 } 532 541 533 - if (!ret_v4) 534 - nic_matcher->ste_builder = nic_matcher->ste_builder4; 535 - else 536 - nic_matcher->ste_builder = nic_matcher->ste_builder6; 542 + return 0; 543 + } 544 + 545 + static int dr_matcher_init_nic(struct mlx5dr_matcher *matcher, 546 + struct mlx5dr_matcher_rx_tx *nic_matcher) 547 + { 548 + struct mlx5dr_domain *dmn = matcher->tbl->dmn; 549 + int ret; 550 + 551 + ret = dr_matcher_set_all_ste_builders(matcher, nic_matcher); 552 + if (ret) 553 + return ret; 537 554 538 555 nic_matcher->e_anchor = mlx5dr_ste_htbl_alloc(dmn->ste_icm_pool, 539 556 DR_CHUNK_SIZE_1,
+7 -6
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
··· 954 954 return 0; 955 955 } 956 956 957 - static bool dr_rule_is_ipv6(struct mlx5dr_match_param *param) 957 + static enum mlx5dr_ipv dr_rule_get_ipv(struct mlx5dr_match_spec *spec) 958 958 { 959 - return (param->outer.ip_version == 6 || 960 - param->inner.ip_version == 6 || 961 - param->outer.ethertype == ETH_P_IPV6 || 962 - param->inner.ethertype == ETH_P_IPV6); 959 + if (spec->ip_version == 6 || spec->ethertype == ETH_P_IPV6) 960 + return DR_RULE_IPV6; 961 + 962 + return DR_RULE_IPV4; 963 963 } 964 964 965 965 static bool dr_rule_skip(enum mlx5dr_domain_type domain, ··· 1023 1023 1024 1024 ret = mlx5dr_matcher_select_builders(matcher, 1025 1025 nic_matcher, 1026 - dr_rule_is_ipv6(param)); 1026 + dr_rule_get_ipv(&param->outer), 1027 + dr_rule_get_ipv(&param->inner)); 1027 1028 if (ret) 1028 1029 goto out_err; 1029 1030
+9 -1
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
··· 2 2 /* Copyright (c) 2019 Mellanox Technologies. */ 3 3 4 4 #include <linux/types.h> 5 + #include <linux/crc32.h> 5 6 #include "dr_types.h" 6 7 7 8 #define DR_STE_CRC_POLY 0xEDB88320L ··· 108 107 u8 mask[DR_STE_SIZE_MASK]; 109 108 }; 110 109 110 + static u32 dr_ste_crc32_calc(const void *input_data, size_t length) 111 + { 112 + u32 crc = crc32(0, input_data, length); 113 + 114 + return htonl(crc); 115 + } 116 + 111 117 u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl) 112 118 { 113 119 struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p; ··· 136 128 bit = bit >> 1; 137 129 } 138 130 139 - crc32 = mlx5dr_crc32_slice8_calc(masked, DR_STE_SIZE_TAG); 131 + crc32 = dr_ste_crc32_calc(masked, DR_STE_SIZE_TAG); 140 132 index = crc32 & (htbl->chunk->num_of_entries - 1); 141 133 142 134 return index;
+12 -8
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h
··· 106 106 DR_ACTION_TYP_MAX, 107 107 }; 108 108 109 + enum mlx5dr_ipv { 110 + DR_RULE_IPV4, 111 + DR_RULE_IPV6, 112 + DR_RULE_IPV_MAX, 113 + }; 114 + 109 115 struct mlx5dr_icm_pool; 110 116 struct mlx5dr_icm_chunk; 111 117 struct mlx5dr_icm_bucket; ··· 685 679 struct mlx5dr_ste_htbl *s_htbl; 686 680 struct mlx5dr_ste_htbl *e_anchor; 687 681 struct mlx5dr_ste_build *ste_builder; 688 - struct mlx5dr_ste_build ste_builder4[DR_RULE_MAX_STES]; 689 - struct mlx5dr_ste_build ste_builder6[DR_RULE_MAX_STES]; 682 + struct mlx5dr_ste_build ste_builder_arr[DR_RULE_IPV_MAX] 683 + [DR_RULE_IPV_MAX] 684 + [DR_RULE_MAX_STES]; 690 685 u8 num_of_builders; 691 - u8 num_of_builders4; 692 - u8 num_of_builders6; 686 + u8 num_of_builders_arr[DR_RULE_IPV_MAX][DR_RULE_IPV_MAX]; 693 687 u64 default_icm_addr; 694 688 struct mlx5dr_table_rx_tx *nic_tbl; 695 689 }; ··· 818 812 819 813 int mlx5dr_matcher_select_builders(struct mlx5dr_matcher *matcher, 820 814 struct mlx5dr_matcher_rx_tx *nic_matcher, 821 - bool ipv6); 815 + enum mlx5dr_ipv outer_ipv, 816 + enum mlx5dr_ipv inner_ipv); 822 817 823 818 static inline u32 824 819 mlx5dr_icm_pool_chunk_size_to_entries(enum mlx5dr_icm_chunk_size chunk_size) ··· 968 961 void mlx5dr_ste_copy_param(u8 match_criteria, 969 962 struct mlx5dr_match_param *set_param, 970 963 struct mlx5dr_match_parameters *mask); 971 - 972 - void mlx5dr_crc32_init_table(void); 973 - u32 mlx5dr_crc32_slice8_calc(const void *input_data, size_t length); 974 964 975 965 struct mlx5dr_qp { 976 966 struct mlx5_core_dev *mdev;
+18 -20
drivers/net/ethernet/mellanox/mlx5/core/wq.c
··· 34 34 #include "wq.h" 35 35 #include "mlx5_core.h" 36 36 37 - u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq) 38 - { 39 - return (u32)wq->fbc.sz_m1 + 1; 40 - } 41 - 42 - u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq) 43 - { 44 - return wq->fbc.sz_m1 + 1; 45 - } 46 - 47 - u8 mlx5_cqwq_get_log_stride_size(struct mlx5_cqwq *wq) 48 - { 49 - return wq->fbc.log_stride; 50 - } 51 - 52 - u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq) 53 - { 54 - return (u32)wq->fbc.sz_m1 + 1; 55 - } 56 - 57 37 static u32 wq_get_byte_sz(u8 log_sz, u8 log_stride) 58 38 { 59 39 return ((u32)1 << log_sz) << log_stride; ··· 74 94 mlx5_db_free(mdev, &wq_ctrl->db); 75 95 76 96 return err; 97 + } 98 + 99 + void mlx5_wq_cyc_wqe_dump(struct mlx5_wq_cyc *wq, u16 ix, u8 nstrides) 100 + { 101 + size_t len; 102 + void *wqe; 103 + 104 + if (!net_ratelimit()) 105 + return; 106 + 107 + nstrides = max_t(u8, nstrides, 1); 108 + 109 + len = nstrides << wq->fbc.log_stride; 110 + wqe = mlx5_wq_cyc_get_wqe(wq, ix); 111 + 112 + pr_info("WQE DUMP: WQ size %d WQ cur size %d, WQE index 0x%x, len: %ld\n", 113 + mlx5_wq_cyc_get_size(wq), wq->cur_sz, ix, len); 114 + print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, wqe, len, false); 77 115 } 78 116 79 117 int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
+21 -4
drivers/net/ethernet/mellanox/mlx5/core/wq.h
··· 79 79 int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 80 80 void *wqc, struct mlx5_wq_cyc *wq, 81 81 struct mlx5_wq_ctrl *wq_ctrl); 82 - u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq); 82 + void mlx5_wq_cyc_wqe_dump(struct mlx5_wq_cyc *wq, u16 ix, u8 nstrides); 83 83 84 84 int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 85 85 void *qpc, struct mlx5_wq_qp *wq, ··· 88 88 int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 89 89 void *cqc, struct mlx5_cqwq *wq, 90 90 struct mlx5_wq_ctrl *wq_ctrl); 91 - u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq); 92 - u8 mlx5_cqwq_get_log_stride_size(struct mlx5_cqwq *wq); 93 91 94 92 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 95 93 void *wqc, struct mlx5_wq_ll *wq, 96 94 struct mlx5_wq_ctrl *wq_ctrl); 97 - u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq); 98 95 99 96 void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl); 97 + 98 + static inline u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq) 99 + { 100 + return (u32)wq->fbc.sz_m1 + 1; 101 + } 100 102 101 103 static inline int mlx5_wq_cyc_is_full(struct mlx5_wq_cyc *wq) 102 104 { ··· 170 168 return !equal && !smaller; 171 169 } 172 170 171 + static inline u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq) 172 + { 173 + return wq->fbc.sz_m1 + 1; 174 + } 175 + 176 + static inline u8 mlx5_cqwq_get_log_stride_size(struct mlx5_cqwq *wq) 177 + { 178 + return wq->fbc.log_stride; 179 + } 180 + 173 181 static inline u32 mlx5_cqwq_ctr2ix(struct mlx5_cqwq *wq, u32 ctr) 174 182 { 175 183 return ctr & wq->fbc.sz_m1; ··· 234 222 dma_rmb(); 235 223 236 224 return cqe; 225 + } 226 + 227 + static inline u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq) 228 + { 229 + return (u32)wq->fbc.sz_m1 + 1; 237 230 } 238 231 239 232 static inline int mlx5_wq_ll_is_full(struct mlx5_wq_ll *wq)