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

Merge tag 'mlx5-updates-2017-04-22' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-updates-2017-04-22

Sparse and compiler warnings fixes from Stephen Hemminger.

From Roi Dayan and Or Gerlitz, Add devlink and mlx5 support for controlling
E-Switch encapsulation mode, this knob will enable HW support for applying
encapsulation/decapsulation to VF traffic as part of SRIOV e-switch offloading.
====================

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

+179 -48
+1
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
··· 39 39 #include "en.h" 40 40 #include "en_tc.h" 41 41 #include "eswitch.h" 42 + #include "ipoib.h" 42 43 43 44 static inline bool mlx5e_rx_hw_stamp(struct mlx5e_tstamp *tstamp) 44 45 {
+1
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
··· 33 33 #include <linux/tcp.h> 34 34 #include <linux/if_vlan.h> 35 35 #include "en.h" 36 + #include "ipoib.h" 36 37 37 38 #define MLX5E_SQ_NOPS_ROOM MLX5_SEND_WQE_MAX_WQEBBS 38 39 #define MLX5E_SQ_STOP_ROOM (MLX5_SEND_WQE_MAX_WQEBBS +\
+5
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
··· 1806 1806 esw->enabled_vports = 0; 1807 1807 esw->mode = SRIOV_NONE; 1808 1808 esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE; 1809 + if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) && 1810 + MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap)) 1811 + esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC; 1812 + else 1813 + esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE; 1809 1814 1810 1815 dev->priv.eswitch = esw; 1811 1816 return 0;
+3
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
··· 210 210 DECLARE_HASHTABLE(encap_tbl, 8); 211 211 u8 inline_mode; 212 212 u64 num_flows; 213 + u8 encap; 213 214 }; 214 215 215 216 struct mlx5_eswitch { ··· 323 322 int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode); 324 323 int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode); 325 324 int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode); 325 + int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap); 326 + int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap); 326 327 void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, 327 328 int vport_index, 328 329 struct mlx5_eswitch_rep *rep);
+122 -34
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
··· 426 426 return err; 427 427 } 428 428 429 - #define MAX_PF_SQ 256 430 429 #define ESW_OFFLOADS_NUM_GROUPS 4 431 430 432 - static int esw_create_offloads_fdb_table(struct mlx5_eswitch *esw, int nvports) 431 + static int esw_create_offloads_fast_fdb_table(struct mlx5_eswitch *esw) 433 432 { 434 - int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 435 - struct mlx5_flow_table_attr ft_attr = {}; 436 - int table_size, ix, esw_size, err = 0; 437 433 struct mlx5_core_dev *dev = esw->dev; 438 434 struct mlx5_flow_namespace *root_ns; 439 435 struct mlx5_flow_table *fdb = NULL; 440 - struct mlx5_flow_group *g; 441 - u32 *flow_group_in; 442 - void *match_criteria; 436 + int esw_size, err = 0; 443 437 u32 flags = 0; 444 438 439 + root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_FDB); 440 + if (!root_ns) { 441 + esw_warn(dev, "Failed to get FDB flow namespace\n"); 442 + err = -EOPNOTSUPP; 443 + goto out; 444 + } 445 + 446 + esw_debug(dev, "Create offloads FDB table, min (max esw size(2^%d), max counters(%d)*groups(%d))\n", 447 + MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size), 448 + MLX5_CAP_GEN(dev, max_flow_counter), ESW_OFFLOADS_NUM_GROUPS); 449 + 450 + esw_size = min_t(int, MLX5_CAP_GEN(dev, max_flow_counter) * ESW_OFFLOADS_NUM_GROUPS, 451 + 1 << MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size)); 452 + 453 + if (esw->offloads.encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE) 454 + flags |= MLX5_FLOW_TABLE_TUNNEL_EN; 455 + 456 + fdb = mlx5_create_auto_grouped_flow_table(root_ns, FDB_FAST_PATH, 457 + esw_size, 458 + ESW_OFFLOADS_NUM_GROUPS, 0, 459 + flags); 460 + if (IS_ERR(fdb)) { 461 + err = PTR_ERR(fdb); 462 + esw_warn(dev, "Failed to create Fast path FDB Table err %d\n", err); 463 + goto out; 464 + } 465 + esw->fdb_table.fdb = fdb; 466 + 467 + out: 468 + return err; 469 + } 470 + 471 + static void esw_destroy_offloads_fast_fdb_table(struct mlx5_eswitch *esw) 472 + { 473 + mlx5_destroy_flow_table(esw->fdb_table.fdb); 474 + } 475 + 476 + #define MAX_PF_SQ 256 477 + 478 + static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports) 479 + { 480 + int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 481 + struct mlx5_flow_table_attr ft_attr = {}; 482 + struct mlx5_core_dev *dev = esw->dev; 483 + struct mlx5_flow_namespace *root_ns; 484 + struct mlx5_flow_table *fdb = NULL; 485 + int table_size, ix, err = 0; 486 + struct mlx5_flow_group *g; 487 + void *match_criteria; 488 + u32 *flow_group_in; 489 + 490 + esw_debug(esw->dev, "Create offloads FDB Tables\n"); 445 491 flow_group_in = mlx5_vzalloc(inlen); 446 492 if (!flow_group_in) 447 493 return -ENOMEM; ··· 499 453 goto ns_err; 500 454 } 501 455 502 - esw_debug(dev, "Create offloads FDB table, min (max esw size(2^%d), max counters(%d)*groups(%d))\n", 503 - MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size), 504 - MLX5_CAP_GEN(dev, max_flow_counter), ESW_OFFLOADS_NUM_GROUPS); 505 - 506 - esw_size = min_t(int, MLX5_CAP_GEN(dev, max_flow_counter) * ESW_OFFLOADS_NUM_GROUPS, 507 - 1 << MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size)); 508 - 509 - if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) && 510 - MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap)) 511 - flags |= MLX5_FLOW_TABLE_TUNNEL_EN; 512 - 513 - fdb = mlx5_create_auto_grouped_flow_table(root_ns, FDB_FAST_PATH, 514 - esw_size, 515 - ESW_OFFLOADS_NUM_GROUPS, 0, 516 - flags); 517 - if (IS_ERR(fdb)) { 518 - err = PTR_ERR(fdb); 519 - esw_warn(dev, "Failed to create Fast path FDB Table err %d\n", err); 456 + err = esw_create_offloads_fast_fdb_table(esw); 457 + if (err) 520 458 goto fast_fdb_err; 521 - } 522 - esw->fdb_table.fdb = fdb; 523 459 524 460 table_size = nvports + MAX_PF_SQ + 1; 525 461 ··· 573 545 return err; 574 546 } 575 547 576 - static void esw_destroy_offloads_fdb_table(struct mlx5_eswitch *esw) 548 + static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw) 577 549 { 578 550 if (!esw->fdb_table.fdb) 579 551 return; 580 552 581 - esw_debug(esw->dev, "Destroy offloads FDB Table\n"); 553 + esw_debug(esw->dev, "Destroy offloads FDB Tables\n"); 582 554 mlx5_del_flow_rules(esw->fdb_table.offloads.miss_rule); 583 555 mlx5_destroy_flow_group(esw->fdb_table.offloads.send_to_vport_grp); 584 556 mlx5_destroy_flow_group(esw->fdb_table.offloads.miss_grp); 585 557 586 558 mlx5_destroy_flow_table(esw->fdb_table.offloads.fdb); 587 - mlx5_destroy_flow_table(esw->fdb_table.fdb); 559 + esw_destroy_offloads_fast_fdb_table(esw); 588 560 } 589 561 590 562 static int esw_create_offloads_table(struct mlx5_eswitch *esw) ··· 744 716 mlx5_remove_dev_by_protocol(esw->dev, MLX5_INTERFACE_PROTOCOL_IB); 745 717 mlx5_dev_list_unlock(); 746 718 747 - err = esw_create_offloads_fdb_table(esw, nvports); 719 + err = esw_create_offloads_fdb_tables(esw, nvports); 748 720 if (err) 749 721 goto create_fdb_err; 750 722 ··· 781 753 esw_destroy_offloads_table(esw); 782 754 783 755 create_ft_err: 784 - esw_destroy_offloads_fdb_table(esw); 756 + esw_destroy_offloads_fdb_tables(esw); 785 757 786 758 create_fdb_err: 787 759 /* enable back PF RoCE */ ··· 827 799 828 800 esw_destroy_vport_rx_group(esw); 829 801 esw_destroy_offloads_table(esw); 830 - esw_destroy_offloads_fdb_table(esw); 802 + esw_destroy_offloads_fdb_tables(esw); 831 803 } 832 804 833 805 static int esw_mode_from_devlink(u16 mode, u16 *mlx5_mode) ··· 1041 1013 } 1042 1014 1043 1015 *mode = mlx5_mode; 1016 + return 0; 1017 + } 1018 + 1019 + int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap) 1020 + { 1021 + struct mlx5_core_dev *dev = devlink_priv(devlink); 1022 + struct mlx5_eswitch *esw = dev->priv.eswitch; 1023 + int err; 1024 + 1025 + if (!MLX5_CAP_GEN(dev, vport_group_manager)) 1026 + return -EOPNOTSUPP; 1027 + 1028 + if (esw->mode == SRIOV_NONE) 1029 + return -EOPNOTSUPP; 1030 + 1031 + if (encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE && 1032 + (!MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) || 1033 + !MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap))) 1034 + return -EOPNOTSUPP; 1035 + 1036 + if (encap && encap != DEVLINK_ESWITCH_ENCAP_MODE_BASIC) 1037 + return -EOPNOTSUPP; 1038 + 1039 + if (esw->mode == SRIOV_LEGACY) { 1040 + esw->offloads.encap = encap; 1041 + return 0; 1042 + } 1043 + 1044 + if (esw->offloads.encap == encap) 1045 + return 0; 1046 + 1047 + if (esw->offloads.num_flows > 0) { 1048 + esw_warn(dev, "Can't set encapsulation when flows are configured\n"); 1049 + return -EOPNOTSUPP; 1050 + } 1051 + 1052 + esw_destroy_offloads_fast_fdb_table(esw); 1053 + 1054 + esw->offloads.encap = encap; 1055 + err = esw_create_offloads_fast_fdb_table(esw); 1056 + if (err) { 1057 + esw_warn(esw->dev, "Failed re-creating fast FDB table, err %d\n", err); 1058 + esw->offloads.encap = !encap; 1059 + (void) esw_create_offloads_fast_fdb_table(esw); 1060 + } 1061 + return err; 1062 + } 1063 + 1064 + int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap) 1065 + { 1066 + struct mlx5_core_dev *dev = devlink_priv(devlink); 1067 + struct mlx5_eswitch *esw = dev->priv.eswitch; 1068 + 1069 + if (!MLX5_CAP_GEN(dev, vport_group_manager)) 1070 + return -EOPNOTSUPP; 1071 + 1072 + if (esw->mode == SRIOV_NONE) 1073 + return -EOPNOTSUPP; 1074 + 1075 + *encap = esw->offloads.encap; 1044 1076 return 0; 1045 1077 } 1046 1078
+13 -11
drivers/net/ethernet/mellanox/mlx5/core/ipoib.c
··· 178 178 return 0; 179 179 } 180 180 181 - void mlx5i_cleanup_tx(struct mlx5e_priv *priv) 181 + static void mlx5i_cleanup_tx(struct mlx5e_priv *priv) 182 182 { 183 183 struct mlx5i_priv *ipriv = priv->ppriv; 184 184 ··· 359 359 return 0; 360 360 } 361 361 362 + #ifdef notusedyet 362 363 /* IPoIB RDMA netdev callbacks */ 363 - int mlx5i_attach_mcast(struct net_device *netdev, struct ib_device *hca, 364 - union ib_gid *gid, u16 lid, int set_qkey) 364 + static int mlx5i_attach_mcast(struct net_device *netdev, struct ib_device *hca, 365 + union ib_gid *gid, u16 lid, int set_qkey) 365 366 { 366 367 struct mlx5e_priv *epriv = mlx5i_epriv(netdev); 367 368 struct mlx5_core_dev *mdev = epriv->mdev; ··· 378 377 return err; 379 378 } 380 379 381 - int mlx5i_detach_mcast(struct net_device *netdev, struct ib_device *hca, 382 - union ib_gid *gid, u16 lid) 380 + static int mlx5i_detach_mcast(struct net_device *netdev, struct ib_device *hca, 381 + union ib_gid *gid, u16 lid) 383 382 { 384 383 struct mlx5e_priv *epriv = mlx5i_epriv(netdev); 385 384 struct mlx5_core_dev *mdev = epriv->mdev; ··· 396 395 return err; 397 396 } 398 397 399 - int mlx5i_xmit(struct net_device *dev, struct sk_buff *skb, 398 + static int mlx5i_xmit(struct net_device *dev, struct sk_buff *skb, 400 399 struct ib_ah *address, u32 dqpn, u32 dqkey) 401 400 { 402 401 struct mlx5e_priv *epriv = mlx5i_epriv(dev); ··· 405 404 406 405 return mlx5i_sq_xmit(sq, skb, &mah->av, dqpn, dqkey); 407 406 } 407 + #endif 408 408 409 409 static int mlx5i_check_required_hca_cap(struct mlx5_core_dev *mdev) 410 410 { ··· 420 418 return 0; 421 419 } 422 420 423 - struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, 424 - struct ib_device *ibdev, 425 - const char *name, 426 - void (*setup)(struct net_device *)) 421 + static struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, 422 + struct ib_device *ibdev, 423 + const char *name, 424 + void (*setup)(struct net_device *)) 427 425 { 428 426 const struct mlx5e_profile *profile = &mlx5i_nic_profile; 429 427 int nch = profile->max_nch(mdev); ··· 482 480 } 483 481 EXPORT_SYMBOL(mlx5_rdma_netdev_alloc); 484 482 485 - void mlx5_rdma_netdev_free(struct net_device *netdev) 483 + static void mlx5_rdma_netdev_free(struct net_device *netdev) 486 484 { 487 485 struct mlx5e_priv *priv = mlx5i_epriv(netdev); 488 486 const struct mlx5e_profile *profile = priv->profile;
+2
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 1280 1280 .eswitch_mode_get = mlx5_devlink_eswitch_mode_get, 1281 1281 .eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set, 1282 1282 .eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get, 1283 + .eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set, 1284 + .eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get, 1283 1285 #endif 1284 1286 }; 1285 1287
+2
include/net/devlink.h
··· 268 268 int (*eswitch_mode_set)(struct devlink *devlink, u16 mode); 269 269 int (*eswitch_inline_mode_get)(struct devlink *devlink, u8 *p_inline_mode); 270 270 int (*eswitch_inline_mode_set)(struct devlink *devlink, u8 inline_mode); 271 + int (*eswitch_encap_mode_get)(struct devlink *devlink, u8 *p_encap_mode); 272 + int (*eswitch_encap_mode_set)(struct devlink *devlink, u8 encap_mode); 271 273 }; 272 274 273 275 static inline void *devlink_priv(struct devlink *devlink)
+7
include/uapi/linux/devlink.h
··· 119 119 DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT, 120 120 }; 121 121 122 + enum devlink_eswitch_encap_mode { 123 + DEVLINK_ESWITCH_ENCAP_MODE_NONE, 124 + DEVLINK_ESWITCH_ENCAP_MODE_BASIC, 125 + }; 126 + 122 127 enum devlink_attr { 123 128 /* don't change the order or add anything between, this is ABI! */ 124 129 DEVLINK_ATTR_UNSPEC, ··· 199 194 DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, /* u32 */ 200 195 201 196 DEVLINK_ATTR_PAD, 197 + 198 + DEVLINK_ATTR_ESWITCH_ENCAP_MODE, /* u8 */ 202 199 203 200 /* add new attributes above here, update the policy in devlink.c */ 204 201
+23 -3
net/core/devlink.c
··· 1397 1397 u32 seq, int flags) 1398 1398 { 1399 1399 const struct devlink_ops *ops = devlink->ops; 1400 + u8 inline_mode, encap_mode; 1400 1401 void *hdr; 1401 1402 int err = 0; 1402 1403 u16 mode; 1403 - u8 inline_mode; 1404 1404 1405 1405 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 1406 1406 if (!hdr) ··· 1425 1425 goto nla_put_failure; 1426 1426 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, 1427 1427 inline_mode); 1428 + if (err) 1429 + goto nla_put_failure; 1430 + } 1431 + 1432 + if (ops->eswitch_encap_mode_get) { 1433 + err = ops->eswitch_encap_mode_get(devlink, &encap_mode); 1434 + if (err) 1435 + goto nla_put_failure; 1436 + err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); 1428 1437 if (err) 1429 1438 goto nla_put_failure; 1430 1439 } ··· 1477 1468 { 1478 1469 struct devlink *devlink = info->user_ptr[0]; 1479 1470 const struct devlink_ops *ops = devlink->ops; 1480 - u16 mode; 1481 - u8 inline_mode; 1471 + u8 inline_mode, encap_mode; 1482 1472 int err = 0; 1473 + u16 mode; 1483 1474 1484 1475 if (!ops) 1485 1476 return -EOPNOTSUPP; ··· 1502 1493 if (err) 1503 1494 return err; 1504 1495 } 1496 + 1497 + if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { 1498 + if (!ops->eswitch_encap_mode_set) 1499 + return -EOPNOTSUPP; 1500 + encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); 1501 + err = ops->eswitch_encap_mode_set(devlink, encap_mode); 1502 + if (err) 1503 + return err; 1504 + } 1505 + 1505 1506 return 0; 1506 1507 } 1507 1508 ··· 2209 2190 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, 2210 2191 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 }, 2211 2192 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 }, 2193 + [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, 2212 2194 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, 2213 2195 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, 2214 2196 };