Commit 66e037ca authored by David S. Miller's avatar David S. Miller

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

Saeed Mahameed says:

====================
mlx5-updates-2017-06-11

This series provides updates to mlx5 header rewrite feature, from Or Gerlitz.
and three more small updates From maor and eran.

-------
Or says:

Packets belonging to flows which are different by matching may still need
to go through the same header re-writes (e.g set the current routing hop
MACs and issue TTL decrement).  To minimize the number of modify header
IDs, we add a cache for header re-write IDs which is keyed by the binary
chain of modify header actions.

The caching is supported for both eswitch and NIC use-cases, where the
actual conversion of the code to use caching comes in separate patches,
one per use-case.

Using a per field mask field, the TC pedit action supports modifying
partial fields. The last patch enables offloading that.
-------

From Maor, update flow table commands layout to the latest HW spec.
From Eran, ethtool connector type reporting updates.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6d307f6b 46e9d0b6
......@@ -623,6 +623,8 @@ struct mlx5e_tc_table {
struct rhashtable_params ht_params;
struct rhashtable ht;
DECLARE_HASHTABLE(mod_hdr_tbl, 8);
};
struct mlx5e_vlan_table {
......
......@@ -723,24 +723,81 @@ static void ptys2ethtool_adver_link(unsigned long *advertising_modes,
__ETHTOOL_LINK_MODE_MASK_NBITS);
}
static void ptys2ethtool_supported_port(struct ethtool_link_ksettings *link_ksettings,
u32 eth_proto_cap)
static void ptys2ethtool_supported_advertised_port(struct ethtool_link_ksettings *link_ksettings,
u32 eth_proto_cap,
u8 connector_type)
{
if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
| MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
| MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
| MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
| MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
| MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
ethtool_link_ksettings_add_link_mode(link_ksettings, supported, FIBRE);
if (!connector_type || connector_type >= MLX5E_CONNECTOR_TYPE_NUMBER) {
if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
| MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
| MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
| MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
| MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
| MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
ethtool_link_ksettings_add_link_mode(link_ksettings,
supported,
FIBRE);
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising,
FIBRE);
}
if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
| MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
| MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
| MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
| MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
ethtool_link_ksettings_add_link_mode(link_ksettings,
supported,
Backplane);
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising,
Backplane);
}
return;
}
if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
| MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
| MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
| MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
| MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Backplane);
switch (connector_type) {
case MLX5E_PORT_TP:
ethtool_link_ksettings_add_link_mode(link_ksettings,
supported, TP);
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising, TP);
break;
case MLX5E_PORT_AUI:
ethtool_link_ksettings_add_link_mode(link_ksettings,
supported, AUI);
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising, AUI);
break;
case MLX5E_PORT_BNC:
ethtool_link_ksettings_add_link_mode(link_ksettings,
supported, BNC);
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising, BNC);
break;
case MLX5E_PORT_MII:
ethtool_link_ksettings_add_link_mode(link_ksettings,
supported, MII);
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising, MII);
break;
case MLX5E_PORT_FIBRE:
ethtool_link_ksettings_add_link_mode(link_ksettings,
supported, FIBRE);
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising, FIBRE);
break;
case MLX5E_PORT_DA:
ethtool_link_ksettings_add_link_mode(link_ksettings,
supported, Backplane);
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising, Backplane);
break;
case MLX5E_PORT_NONE:
case MLX5E_PORT_OTHER:
default:
break;
}
}
......@@ -791,7 +848,6 @@ static void get_supported(u32 eth_proto_cap,
{
unsigned long *supported = link_ksettings->link_modes.supported;
ptys2ethtool_supported_port(link_ksettings, eth_proto_cap);
ptys2ethtool_supported_link(supported, eth_proto_cap);
ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause);
}
......@@ -809,8 +865,23 @@ static void get_advertising(u32 eth_proto_cap, u8 tx_pause,
ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Asym_Pause);
}
static u8 get_connector_port(u32 eth_proto)
static int ptys2connector_type[MLX5E_CONNECTOR_TYPE_NUMBER] = {
[MLX5E_PORT_UNKNOWN] = PORT_OTHER,
[MLX5E_PORT_NONE] = PORT_NONE,
[MLX5E_PORT_TP] = PORT_TP,
[MLX5E_PORT_AUI] = PORT_AUI,
[MLX5E_PORT_BNC] = PORT_BNC,
[MLX5E_PORT_MII] = PORT_MII,
[MLX5E_PORT_FIBRE] = PORT_FIBRE,
[MLX5E_PORT_DA] = PORT_DA,
[MLX5E_PORT_OTHER] = PORT_OTHER,
};
static u8 get_connector_port(u32 eth_proto, u8 connector_type)
{
if (connector_type && connector_type < MLX5E_CONNECTOR_TYPE_NUMBER)
return ptys2connector_type[connector_type];
if (eth_proto & (MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
| MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
| MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
......@@ -856,6 +927,7 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev,
u32 eth_proto_oper;
u8 an_disable_admin;
u8 an_status;
u8 connector_type;
int err;
err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
......@@ -871,6 +943,7 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev,
eth_proto_lp = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
an_disable_admin = MLX5_GET(ptys_reg, out, an_disable_admin);
an_status = MLX5_GET(ptys_reg, out, an_status);
connector_type = MLX5_GET(ptys_reg, out, connector_type);
mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
......@@ -883,7 +956,10 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev,
eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
link_ksettings->base.port = get_connector_port(eth_proto_oper);
link_ksettings->base.port = get_connector_port(eth_proto_oper,
connector_type);
ptys2ethtool_supported_advertised_port(link_ksettings, eth_proto_admin,
connector_type);
get_lp_advertising(eth_proto_lp, link_ksettings);
if (an_status == MLX5_AN_COMPLETE)
......
......@@ -1769,6 +1769,7 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
}
hash_init(esw->offloads.encap_tbl);
hash_init(esw->offloads.mod_hdr_tbl);
mutex_init(&esw->state_lock);
for (vport_num = 0; vport_num < total_vports; vport_num++) {
......
......@@ -207,6 +207,7 @@ struct mlx5_esw_offload {
struct mlx5_flow_group *vport_rx_group;
struct mlx5_eswitch_rep *vport_reps;
DECLARE_HASHTABLE(encap_tbl, 8);
DECLARE_HASHTABLE(mod_hdr_tbl, 8);
u8 inline_mode;
u64 num_flows;
u8 encap;
......
......@@ -78,28 +78,33 @@ int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
MLX5_CMD_OP_CREATE_FLOW_TABLE);
MLX5_SET(create_flow_table_in, in, table_type, type);
MLX5_SET(create_flow_table_in, in, level, level);
MLX5_SET(create_flow_table_in, in, log_size, log_size);
MLX5_SET(create_flow_table_in, in, flow_table_context.level, level);
MLX5_SET(create_flow_table_in, in, flow_table_context.log_size, log_size);
if (vport) {
MLX5_SET(create_flow_table_in, in, vport_number, vport);
MLX5_SET(create_flow_table_in, in, other_vport, 1);
}
MLX5_SET(create_flow_table_in, in, decap_en, en_encap_decap);
MLX5_SET(create_flow_table_in, in, encap_en, en_encap_decap);
MLX5_SET(create_flow_table_in, in, flow_table_context.decap_en,
en_encap_decap);
MLX5_SET(create_flow_table_in, in, flow_table_context.encap_en,
en_encap_decap);
switch (op_mod) {
case FS_FT_OP_MOD_NORMAL:
if (next_ft) {
MLX5_SET(create_flow_table_in, in, table_miss_mode, 1);
MLX5_SET(create_flow_table_in, in, table_miss_id, next_ft->id);
MLX5_SET(create_flow_table_in, in,
flow_table_context.table_miss_action, 1);
MLX5_SET(create_flow_table_in, in,
flow_table_context.table_miss_id, next_ft->id);
}
break;
case FS_FT_OP_MOD_LAG_DEMUX:
MLX5_SET(create_flow_table_in, in, op_mod, 0x1);
if (next_ft)
MLX5_SET(create_flow_table_in, in, lag_master_next_table_id,
MLX5_SET(create_flow_table_in, in,
flow_table_context.lag_master_next_table_id,
next_ft->id);
break;
}
......@@ -146,10 +151,10 @@ int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev,
MLX5_MODIFY_FLOW_TABLE_LAG_NEXT_TABLE_ID);
if (next_ft) {
MLX5_SET(modify_flow_table_in, in,
lag_master_next_table_id, next_ft->id);
flow_table_context.lag_master_next_table_id, next_ft->id);
} else {
MLX5_SET(modify_flow_table_in, in,
lag_master_next_table_id, 0);
flow_table_context.lag_master_next_table_id, 0);
}
} else {
if (ft->vport) {
......@@ -160,11 +165,14 @@ int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev,
MLX5_SET(modify_flow_table_in, in, modify_field_select,
MLX5_MODIFY_FLOW_TABLE_MISS_TABLE_ID);
if (next_ft) {
MLX5_SET(modify_flow_table_in, in, table_miss_mode, 1);
MLX5_SET(modify_flow_table_in, in, table_miss_id,
MLX5_SET(modify_flow_table_in, in,
flow_table_context.table_miss_action, 1);
MLX5_SET(modify_flow_table_in, in,
flow_table_context.table_miss_id,
next_ft->id);
} else {
MLX5_SET(modify_flow_table_in, in, table_miss_mode, 0);
MLX5_SET(modify_flow_table_in, in,
flow_table_context.table_miss_action, 0);
}
}
......
......@@ -6627,6 +6627,24 @@ struct mlx5_ifc_create_flow_table_out_bits {
u8 reserved_at_60[0x20];
};
struct mlx5_ifc_flow_table_context_bits {
u8 encap_en[0x1];
u8 decap_en[0x1];
u8 reserved_at_2[0x2];
u8 table_miss_action[0x4];
u8 level[0x8];
u8 reserved_at_10[0x8];
u8 log_size[0x8];
u8 reserved_at_20[0x8];
u8 table_miss_id[0x18];
u8 reserved_at_40[0x8];
u8 lag_master_next_table_id[0x18];
u8 reserved_at_60[0xe0];
};
struct mlx5_ifc_create_flow_table_in_bits {
u8 opcode[0x10];
u8 reserved_at_10[0x10];
......@@ -6645,21 +6663,7 @@ struct mlx5_ifc_create_flow_table_in_bits {
u8 reserved_at_a0[0x20];
u8 encap_en[0x1];
u8 decap_en[0x1];
u8 reserved_at_c2[0x2];
u8 table_miss_mode[0x4];
u8 level[0x8];
u8 reserved_at_d0[0x8];
u8 log_size[0x8];
u8 reserved_at_e0[0x8];
u8 table_miss_id[0x18];
u8 reserved_at_100[0x8];
u8 lag_master_next_table_id[0x18];
u8 reserved_at_120[0x80];
struct mlx5_ifc_flow_table_context_bits flow_table_context;
};
struct mlx5_ifc_create_flow_group_out_bits {
......@@ -7291,7 +7295,8 @@ struct mlx5_ifc_ptys_reg_bits {
u8 ib_link_width_oper[0x10];
u8 ib_proto_oper[0x10];
u8 reserved_at_160[0x20];
u8 reserved_at_160[0x1c];
u8 connector_type[0x4];
u8 eth_proto_lp_advertise[0x20];
......@@ -7694,8 +7699,10 @@ struct mlx5_ifc_peir_reg_bits {
};
struct mlx5_ifc_pcam_enhanced_features_bits {
u8 reserved_at_0[0x7e];
u8 reserved_at_0[0x7c];
u8 ptys_connector_type[0x1];
u8 reserved_at_7d[0x1];
u8 ppcnt_discard_group[0x1];
u8 ppcnt_statistical_group[0x1];
};
......@@ -8277,17 +8284,7 @@ struct mlx5_ifc_modify_flow_table_in_bits {
u8 reserved_at_a0[0x8];
u8 table_id[0x18];
u8 reserved_at_c0[0x4];
u8 table_miss_mode[0x4];
u8 reserved_at_c8[0x18];
u8 reserved_at_e0[0x8];
u8 table_miss_id[0x18];
u8 reserved_at_100[0x8];
u8 lag_master_next_table_id[0x18];
u8 reserved_at_120[0x80];
struct mlx5_ifc_flow_table_context_bits flow_table_context;
};
struct mlx5_ifc_ets_tcn_config_reg_bits {
......
......@@ -92,6 +92,19 @@ enum mlx5e_link_mode {
MLX5E_LINK_MODES_NUMBER,
};
enum mlx5e_connector_type {
MLX5E_PORT_UNKNOWN = 0,
MLX5E_PORT_NONE = 1,
MLX5E_PORT_TP = 2,
MLX5E_PORT_AUI = 3,
MLX5E_PORT_BNC = 4,
MLX5E_PORT_MII = 5,
MLX5E_PORT_FIBRE = 6,
MLX5E_PORT_DA = 7,
MLX5E_PORT_OTHER = 8,
MLX5E_CONNECTOR_TYPE_NUMBER,
};
#define MLX5E_PROT_MASK(link_mode) (1 << link_mode)
#define PORT_MODULE_EVENT_MODULE_STATUS_MASK 0xF
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment