[MLX4_BUS] support ModStatConfg command to query if port is enabled or disabled.
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 17 Nov 2009 12:58:33 +0000 (12:58 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 17 Nov 2009 12:58:33 +0000 (12:58 +0000)
Sign off by:urih@mellanox.co.il

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2575 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

hw/mlx4/kernel/bus/drv/drv.c
hw/mlx4/kernel/bus/inc/cmd.h
hw/mlx4/kernel/bus/inc/device.h
hw/mlx4/kernel/bus/net/fw.c
hw/mlx4/kernel/bus/net/fw.h
hw/mlx4/kernel/bus/net/main.c
hw/mlx4/kernel/bus/net/mlx4.h

index b30cc1c..987cbcc 100644 (file)
@@ -221,7 +221,9 @@ Routine Description:
        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
@@ -232,22 +234,38 @@ Routine Description:
        // 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
index 2828527..94f01a4 100644 (file)
@@ -114,6 +114,7 @@ enum {
        /* 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,
index ed0d329..5f6f134 100644 (file)
@@ -208,7 +208,8 @@ struct mlx4_caps {
        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;
 };
 
index 5e8ad60..347810e 100644 (file)
@@ -626,6 +626,54 @@ out:
        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;
index f5113e6..bd2be13 100644 (file)
@@ -160,6 +160,7 @@ int mlx4_MAP_FA(struct mlx4_dev *dev, struct mlx4_icm *icm);
 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);
index c1bf191..9f31dcf 100644 (file)
@@ -148,7 +148,23 @@ int mlx4_count_ib_ports(struct mlx4_dev *dev)
 
 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;
@@ -675,6 +691,12 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
                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;
 
index 599557d..855e6b9 100644 (file)
@@ -65,6 +65,11 @@ enum mlx4_port_type {
        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
@@ -385,6 +390,8 @@ void mlx4_intf_init();
 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;