int number_of_ib_ports;\r
PFDO_DEVICE_DATA p_fdo = FdoGetData(Device);\r
struct mlx4_dev *mdev = p_fdo->pci_dev.dev;\r
-\r
+ BOOLEAN ib_created = FALSE;\r
+ BOOLEAN eth_created = FALSE;\r
+ \r
MLX4_ENTER(MLX4_DBG_DRV);\r
\r
if ( p_fdo->children_created )\r
// this routine will create all the children on base on this info\r
number_of_ib_ports = mlx4_count_ib_ports(mdev);\r
ASSERT(number_of_ib_ports >=0 && number_of_ib_ports <=2);\r
- \r
- if(number_of_ib_ports > 0) {\r
- status = __create_child(Device, BUS_HARDWARE_IDS, BUS_HARDWARE_DESCRIPTION, 0 );\r
- if (!NT_SUCCESS(status)) {\r
- MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (ib)failed with 0x%x\n", status));\r
- }\r
- }\r
\r
- // Create ethernet ports if needed\r
- for (i = 0; i < MLX4_MAX_PORTS; i++) {\r
- if(mlx4_is_eth_port(mdev, i)) {\r
- status = __create_child(Device, ETH_HARDWARE_IDS, ETH_HARDWARE_DESCRIPTION, i+1 );\r
- if (!NT_SUCCESS(status)) {\r
- MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (eth) failed with 0x%x\n", status));\r
- }\r
- }\r
+ for (i = 1; i <= MLX4_MAX_PORTS; i++) {\r
+ if (mlx4_is_enabled_port(mdev, i)) {\r
+ if(mlx4_is_eth_port(mdev, i)) {\r
+ status = __create_child(Device, ETH_HARDWARE_IDS, ETH_HARDWARE_DESCRIPTION, i);\r
+ if (!NT_SUCCESS(status)) {\r
+ MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (eth) failed with 0x%x\n", status));\r
+ break;\r
+ }\r
+ eth_created = TRUE;\r
+ } else {\r
+ if (eth_created){\r
+ //\r
+ // Illegal configuration the IB should be the first port\r
+ //\r
+ status = STATUS_INVALID_PARAMETER;\r
+ MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (IB) failed. Invalid configuration, IB should be the first port."));\r
+ break; \r
+ }\r
+ \r
+ if (ib_created){\r
+ continue;\r
+ }\r
+\r
+ status = __create_child(Device, BUS_HARDWARE_IDS, BUS_HARDWARE_DESCRIPTION, 0 );\r
+ if (!NT_SUCCESS(status)) {\r
+ MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (ib)failed with 0x%x\n", status));\r
+ break;\r
+ }\r
+ ib_created = TRUE;\r
+ }\r
+ }\r
}\r
\r
p_fdo->children_created = TRUE;\r
/* miscellaneous commands */
MLX4_CMD_DIAG_RPRT = 0x30,
MLX4_CMD_NOP = 0x31,
+ MLX4_CMD_QUERY_STAT_CFG = 0x34,
/* debug commands */
MLX4_CMD_QUERY_DEBUG_MSG = 0x2a,
int log_num_prios;
int num_fc_exch;
enum mlx4_port_type port_type[MLX4_MAX_PORTS + 1];
- int reserved_fexch_mpts_base;
+ enum mlx4_port_state port_state[MLX4_MAX_PORTS + 1];
+ int reserved_fexch_mpts_base;
int total_reserved_qps;
};
return err;
}
+
+static int
+query_port_state(struct mlx4_dev *dev, u8 port)
+{
+ int err = 0;
+ u32 input_modifier = 0;
+ u64 out_param;
+
+#define MOD_STAT_OPMOD_QUERY_INLINE 0x3
+#define MOD_STAT_OFFSET_PORT_EN 0x8
+
+ input_modifier = (1 << 28) | (port << 8) | MOD_STAT_OFFSET_PORT_EN;
+
+ err = mlx4_cmd_imm(dev, 0, &out_param, input_modifier,
+ MOD_STAT_OPMOD_QUERY_INLINE,
+ MLX4_CMD_QUERY_STAT_CFG,
+ MLX4_CMD_TIME_CLASS_A);
+ if (err) {
+ return err;
+ }
+
+ dev->caps.port_state[port] = (((out_param >> 20) & 1) ? MLX4_PORT_ENABLED : MLX4_PORT_DISABLED);
+ return 0;
+}
+
+int mlx4_port_state(struct mlx4_dev *dev)
+{
+ u8 i = 0;
+ int err = 0;
+
+
+ for (i = 1; i <= MLX4_MAX_PORTS; ++i)
+ {
+ dev->caps.port_state[i] = MLX4_PORT_ENABLED;
+ }
+
+ for (i = 1; i <= MLX4_MAX_PORTS; ++i)
+ {
+ err = query_port_state(dev, i);
+ if (err)
+ {
+ return err;
+ }
+ }
+
+ return 0;
+}
+
static void get_board_id(u8 *vsd, char *board_id)
{
int i;
int mlx4_UNMAP_FA(struct mlx4_dev *dev);
int mlx4_RUN_FW(struct mlx4_dev *dev);
int mlx4_QUERY_FW(struct mlx4_dev *dev);
+int mlx4_port_state(struct mlx4_dev *dev);
int mlx4_QUERY_ADAPTER(struct mlx4_dev *dev, struct mlx4_adapter *adapter);
int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param);
int mlx4_CLOSE_HCA(struct mlx4_dev *dev, int panic);
BOOLEAN mlx4_is_eth_port(struct mlx4_dev *dev, int port_number)
{
- if (dev->caps.port_type[port_number+1] == MLX4_PORT_TYPE_ETH) {
+ if (dev->caps.port_type[port_number] == MLX4_PORT_TYPE_ETH) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOLEAN mlx4_is_ib_port(struct mlx4_dev *dev, int port_number)
+{
+ if (dev->caps.port_type[port_number] == MLX4_PORT_TYPE_IB){
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOLEAN mlx4_is_enabled_port(struct mlx4_dev *dev, int port_number)
+{
+ if (dev->caps.port_state[port_number] == MLX4_PORT_ENABLED) {
return TRUE;
}
return FALSE;
goto err_stop_fw;
}
+ //
+ // Initilize the port state. It's a new command that is supported only in FW 2.6.1280.
+ //If running on earlier FW version the command can fail. Ignore the error code returned
+ //
+ mlx4_port_state(dev);
+
process_mod_param_profile();
profile = default_profile;
MLX4_PORT_TYPE_ETH = 1 << 1,
};
+enum mlx4_port_state {
+ MLX4_PORT_ENABLED = 1 << 0,
+ MLX4_PORT_DISABLED = 1 << 1,
+};
+
#define MAX_HCA_CARDS 8
#pragma warning(disable:4201) // nameless struct/union
void mlx4_net_init();
BOOLEAN mlx4_is_eth_port(struct mlx4_dev *dev, int port_number);
+BOOLEAN mlx4_is_ib_port(struct mlx4_dev *dev, int port_number);
+BOOLEAN mlx4_is_enabled_port(struct mlx4_dev *dev, int port_number);
int mlx4_count_ib_ports(struct mlx4_dev *dev);
struct mlx4_dev_cap;