Commit 8d0fc7b6 authored by Yevgeny Petrilin's avatar Yevgeny Petrilin Committed by David S. Miller

mlx4_core: Changing link sensing logic

New FW can give clues to driver regarding default port type
and whether or not we should default to link sensing on the port.

2 bits are added to QUERY_PORT command:
1. suggested_type: This bit gives a hint whether the default port type should be
   IB or Ethernet.
   The driver will use this hint in case the user didn't specify explicitly the link layer
   type he wants to set.
2. default_sense: If this bit is set, we would sense the port type on start-up
   and default the port to link sensing
Signed-off-by: default avatarYevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 58a60168
...@@ -577,6 +577,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -577,6 +577,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
MLX4_GET(field, outbox, QUERY_PORT_SUPPORTED_TYPE_OFFSET); MLX4_GET(field, outbox, QUERY_PORT_SUPPORTED_TYPE_OFFSET);
dev_cap->supported_port_types[i] = field & 3; dev_cap->supported_port_types[i] = field & 3;
dev_cap->suggested_type[i] = (field >> 3) & 1;
dev_cap->default_sense[i] = (field >> 4) & 1;
MLX4_GET(field, outbox, QUERY_PORT_MTU_OFFSET); MLX4_GET(field, outbox, QUERY_PORT_MTU_OFFSET);
dev_cap->ib_mtu[i] = field & 0xf; dev_cap->ib_mtu[i] = field & 0xf;
MLX4_GET(field, outbox, QUERY_PORT_WIDTH_OFFSET); MLX4_GET(field, outbox, QUERY_PORT_WIDTH_OFFSET);
......
...@@ -111,6 +111,8 @@ struct mlx4_dev_cap { ...@@ -111,6 +111,8 @@ struct mlx4_dev_cap {
u64 max_icm_sz; u64 max_icm_sz;
int max_gso_sz; int max_gso_sz;
u8 supported_port_types[MLX4_MAX_PORTS + 1]; u8 supported_port_types[MLX4_MAX_PORTS + 1];
u8 suggested_type[MLX4_MAX_PORTS + 1];
u8 default_sense[MLX4_MAX_PORTS + 1];
u8 log_max_macs[MLX4_MAX_PORTS + 1]; u8 log_max_macs[MLX4_MAX_PORTS + 1];
u8 log_max_vlans[MLX4_MAX_PORTS + 1]; u8 log_max_vlans[MLX4_MAX_PORTS + 1];
u32 max_counters; u32 max_counters;
......
...@@ -130,10 +130,11 @@ int log_mtts_per_seg = ilog2(MLX4_MTT_ENTRY_PER_SEG); ...@@ -130,10 +130,11 @@ int log_mtts_per_seg = ilog2(MLX4_MTT_ENTRY_PER_SEG);
module_param_named(log_mtts_per_seg, log_mtts_per_seg, int, 0444); module_param_named(log_mtts_per_seg, log_mtts_per_seg, int, 0444);
MODULE_PARM_DESC(log_mtts_per_seg, "Log2 number of MTT entries per segment (1-7)"); MODULE_PARM_DESC(log_mtts_per_seg, "Log2 number of MTT entries per segment (1-7)");
static int port_type_array[2] = {1, 1}; static int port_type_array[2] = {MLX4_PORT_TYPE_NONE, MLX4_PORT_TYPE_NONE};
static int arr_argc = 2; static int arr_argc = 2;
module_param_array(port_type_array, int, &arr_argc, 0444); module_param_array(port_type_array, int, &arr_argc, 0444);
MODULE_PARM_DESC(port_type_array, "Array of port types: IB by default"); MODULE_PARM_DESC(port_type_array, "Array of port types: HW_DEFAULT (0) is default "
"1 for IB, 2 for Ethernet");
struct mlx4_port_config { struct mlx4_port_config {
struct list_head list; struct list_head list;
...@@ -225,6 +226,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -225,6 +226,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.eth_mtu_cap[i] = dev_cap->eth_mtu[i]; dev->caps.eth_mtu_cap[i] = dev_cap->eth_mtu[i];
dev->caps.def_mac[i] = dev_cap->def_mac[i]; dev->caps.def_mac[i] = dev_cap->def_mac[i];
dev->caps.supported_type[i] = dev_cap->supported_port_types[i]; dev->caps.supported_type[i] = dev_cap->supported_port_types[i];
dev->caps.suggested_type[i] = dev_cap->suggested_type[i];
dev->caps.default_sense[i] = dev_cap->default_sense[i];
dev->caps.trans_type[i] = dev_cap->trans_type[i]; dev->caps.trans_type[i] = dev_cap->trans_type[i];
dev->caps.vendor_oui[i] = dev_cap->vendor_oui[i]; dev->caps.vendor_oui[i] = dev_cap->vendor_oui[i];
dev->caps.wavelength[i] = dev_cap->wavelength[i]; dev->caps.wavelength[i] = dev_cap->wavelength[i];
...@@ -302,22 +305,43 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -302,22 +305,43 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
* first of all check if SRIOV is on */ * first of all check if SRIOV is on */
} else if (dev->flags & MLX4_FLAG_SRIOV) } else if (dev->flags & MLX4_FLAG_SRIOV)
dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH; dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH;
/* if IB and ETH are supported and SRIOV is off
* use module parameters */
else { else {
if (port_type_array[i-1]) /* In non-SRIOV mode, we set the port type
dev->caps.port_type[i] = * according to user selection of port type,
MLX4_PORT_TYPE_IB; * if usere selected none, take the FW hint */
if (port_type_array[i-1] == MLX4_PORT_TYPE_NONE)
dev->caps.port_type[i] = dev->caps.suggested_type[i] ?
MLX4_PORT_TYPE_ETH : MLX4_PORT_TYPE_IB;
else else
dev->caps.port_type[i] = dev->caps.port_type[i] = port_type_array[i-1];
MLX4_PORT_TYPE_ETH;
} }
} }
dev->caps.possible_type[i] = dev->caps.port_type[i]; /*
* Link sensing is allowed on the port if 3 conditions are true:
* 1. Both protocols are supported on the port.
* 2. Different types are supported on the port
* 3. FW declared that it supports link sensing
*/
mlx4_priv(dev)->sense.sense_allowed[i] = mlx4_priv(dev)->sense.sense_allowed[i] =
((dev->caps.supported_type[i] == MLX4_PORT_TYPE_AUTO) && ((dev->caps.supported_type[i] == MLX4_PORT_TYPE_AUTO) &&
(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP) &&
(dev->caps.flags & MLX4_DEV_CAP_FLAG_SENSE_SUPPORT)); (dev->caps.flags & MLX4_DEV_CAP_FLAG_SENSE_SUPPORT));
/*
* If "default_sense" bit is set, we move the port to "AUTO" mode
* and perform sense_port FW command to try and set the correct
* port type from beginning
*/
if (mlx4_priv(dev)->sense.sense_allowed && dev->caps.default_sense[i]) {
enum mlx4_port_type sensed_port = MLX4_PORT_TYPE_NONE;
dev->caps.possible_type[i] = MLX4_PORT_TYPE_AUTO;
mlx4_SENSE_PORT(dev, i, &sensed_port);
if (sensed_port != MLX4_PORT_TYPE_NONE)
dev->caps.port_type[i] = sensed_port;
} else {
dev->caps.possible_type[i] = dev->caps.port_type[i];
}
if (dev->caps.log_num_macs > dev_cap->log_max_macs[i]) { if (dev->caps.log_num_macs > dev_cap->log_max_macs[i]) {
dev->caps.log_num_macs = dev_cap->log_max_macs[i]; dev->caps.log_num_macs = dev_cap->log_max_macs[i];
mlx4_warn(dev, "Requested number of MACs is too much " mlx4_warn(dev, "Requested number of MACs is too much "
...@@ -1329,12 +1353,6 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) ...@@ -1329,12 +1353,6 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
if (!mlx4_is_slave(dev)) { if (!mlx4_is_slave(dev)) {
for (port = 1; port <= dev->caps.num_ports; port++) { for (port = 1; port <= dev->caps.num_ports; port++) {
if (!mlx4_is_mfunc(dev)) {
enum mlx4_port_type port_type = 0;
mlx4_SENSE_PORT(dev, port, &port_type);
if (port_type)
dev->caps.port_type[port] = port_type;
}
ib_port_default_caps = 0; ib_port_default_caps = 0;
err = mlx4_get_port_ib_caps(dev, port, err = mlx4_get_port_ib_caps(dev, port,
&ib_port_default_caps); &ib_port_default_caps);
......
...@@ -303,6 +303,8 @@ struct mlx4_caps { ...@@ -303,6 +303,8 @@ struct mlx4_caps {
int log_num_prios; int log_num_prios;
enum mlx4_port_type port_type[MLX4_MAX_PORTS + 1]; enum mlx4_port_type port_type[MLX4_MAX_PORTS + 1];
u8 supported_type[MLX4_MAX_PORTS + 1]; u8 supported_type[MLX4_MAX_PORTS + 1];
u8 suggested_type[MLX4_MAX_PORTS + 1];
u8 default_sense[MLX4_MAX_PORTS + 1];
u32 port_mask[MLX4_MAX_PORTS + 1]; u32 port_mask[MLX4_MAX_PORTS + 1];
enum mlx4_port_type possible_type[MLX4_MAX_PORTS + 1]; enum mlx4_port_type possible_type[MLX4_MAX_PORTS + 1];
u32 max_counters; u32 max_counters;
......
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