[mlx4] allow mlx4 users to add extra eqs for their internal use.
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 9 Jul 2008 09:07:25 +0000 (09:07 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 9 Jul 2008 09:07:25 +0000 (09:07 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@1353 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

hw/mlx4/kernel/bus/drv/drv.c
hw/mlx4/kernel/bus/drv/drv.h
hw/mlx4/kernel/bus/drv/pdo.c
hw/mlx4/kernel/bus/inc/bus_intf.h
hw/mlx4/kernel/bus/net/cq.c
hw/mlx4/kernel/bus/net/eq.c
hw/mlx4/kernel/bus/net/mlx4.h
hw/mlx4/kernel/inc/vip_dev.h

index 5529add..58c0910 100644 (file)
@@ -917,11 +917,11 @@ __read_registry(WDFDRIVER *hDriver)
                //\r
                status = WdfRegistryQueryULong(hKey, &debugLevel, &value);\r
                if (NT_SUCCESS (status)) \r
-                       g_mlx4_dbg_level = g.DebugPrintLevel = value;\r
+                       g_mlx4_dbg_level = g.bwsd.DebugPrintLevel = value;\r
                \r
                status = WdfRegistryQueryULong(hKey, &debugFlags, &value);\r
                if (NT_SUCCESS (status)) \r
-                       g_mlx4_dbg_flags = g.DebugPrintFlags = value;\r
+                       g_mlx4_dbg_flags = g.bwsd.DebugPrintFlags = value;\r
 \r
                status = WdfRegistryQueryULong(hKey, &numQp, &value);\r
                if (NT_SUCCESS (status)) \r
@@ -1051,8 +1051,8 @@ Return Value:
 \r
 \r
        // global initializations\r
-       g_mlx4_dbg_level = g.DebugPrintLevel = TRACE_LEVEL_VERBOSE;\r
-       g_mlx4_dbg_flags = g.DebugPrintFlags = 0xffff;\r
+       g_mlx4_dbg_level = g.bwsd.DebugPrintLevel = TRACE_LEVEL_VERBOSE;\r
+       g_mlx4_dbg_flags = g.bwsd.DebugPrintFlags = 0xffff;\r
 \r
        MLX4_ENTER(MLX4_DBG_DRV);\r
        MLX4_PRINT(TRACE_LEVEL_INFORMATION, MLX4_DBG_DRV, \r
index 1dc7f2b..1803780 100644 (file)
@@ -68,10 +68,17 @@ typedef struct _FDO_DEVICE_DATA
        res_interrupt_t                         interrupt[MLX4_MAX_INTERRUPTS];\r
        MLX4_BUS_IB_INTERFACE           bus_ib_ifc;\r
        // Data for the Ethernet device\r
+#ifdef _WIN64   \r
+    UCHAR   pad[0x8];\r
+#endif\r
+\r
        struct VipBusIfc                        mtnic_Ifc;\r
 \r
 } FDO_DEVICE_DATA, *PFDO_DEVICE_DATA;\r
 \r
+#ifdef _WIN64   \r
+C_ASSERT((FIELD_OFFSET(FDO_DEVICE_DATA, mtnic_Ifc) % 16) == 0);\r
+#endif\r
 \r
 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_DEVICE_DATA, FdoGetData)\r
 \r
index 33d121f..b8b3b0d 100644 (file)
@@ -184,7 +184,7 @@ Return Value:
 \r
        WdfDeviceSetPowerCapabilities(hChild, &powerCaps);\r
 \r
-       p_fdo->bus_ib_ifc.port_id = SerialNo;\r
+       p_fdo->bus_ib_ifc.port_id = (u8) SerialNo;\r
        p_fdo->bus_ib_ifc.pVipBusIfc = &p_fdo->mtnic_Ifc;\r
        p_fdo->bus_ib_ifc.pVipBusIfc->ulAllocatePortObjSize = MAX_PORT_SIZE;\r
        p_fdo->bus_ib_ifc.register_interface = mlx4_register_interface;\r
@@ -226,6 +226,8 @@ Return Value:
 \r
        p_fdo->bus_ib_ifc.mlx4_interface.mlx4_INIT_PORT = mlx4_INIT_PORT;\r
        p_fdo->bus_ib_ifc.mlx4_interface.mlx4_CLOSE_PORT = mlx4_CLOSE_PORT;\r
+       p_fdo->bus_ib_ifc.mlx4_interface.mlx4_add_eq = mlx4_add_eq;\r
+       p_fdo->bus_ib_ifc.mlx4_interface.mlx4_remove_eq = mlx4_remove_eq;\r
 \r
        \r
        //\r
index e20b3e3..558fc7d 100644 (file)
@@ -12,7 +12,7 @@ struct mlx4_cq_context;
 enum mlx4_qp_state;
 struct mlx4_qp_context;
 enum mlx4_qp_optpar;
-
+struct mlx4_eq;
 
 
 typedef int (*MLX4_REGISTER_INTERFACE)(struct mlx4_interface *intf);
@@ -98,6 +98,20 @@ typedef int (*MLX4_INIT_PORT)(struct mlx4_dev *dev, int port);
 typedef int (*MLX4_CLOSE_PORT)(struct mlx4_dev *dev, int port);
 
 
+typedef
+BOOLEAN
+(*PISR_FUNC)(  
+       IN PVOID  IsrContext
+       );
+
+
+typedef int (*MLX4_ADD_EQ) (struct mlx4_dev *dev, int nent,
+                         u8 intr, PISR_FUNC func, PVOID func_context ,
+                         u8* p_eq_num, struct mlx4_eq ** p_eq);
+
+typedef VOID (*MLX4_REMOVE_EQ) (struct mlx4_dev *dev, u8 eq_num);
+
+
 struct mlx4_interface_ex {
        MLX4_PD_ALLOC       mlx4_pd_alloc;
        MLX4_PD_FREE        mlx4_pd_free;
@@ -141,6 +155,9 @@ struct mlx4_interface_ex {
 
        MLX4_INIT_PORT         mlx4_INIT_PORT;
        MLX4_CLOSE_PORT        mlx4_CLOSE_PORT;
+
+       MLX4_ADD_EQ            mlx4_add_eq;
+       MLX4_REMOVE_EQ         mlx4_remove_eq;
        
 };
 
@@ -154,7 +171,7 @@ typedef struct _MLX4_BUS_IB_INTERFACE{
        int                                                     is_livefish;
        MLX4_REGISTER_INTERFACE     register_interface;
        MLX4_UNREGISTER_INTERFACE   unregister_interface;
-       ULONG                                           port_id;
+       u8                                                      port_id;
        struct VipBusIfc                        *pVipBusIfc;
        
 } MLX4_BUS_IB_INTERFACE, *PMLX4_BUS_IB_INTERFACE;
index 05996ef..d810b35 100644 (file)
@@ -127,7 +127,6 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
        u64 mtt_addr;
        int err;
 
-       UNREFERENCED_PARAMETER(vector);
 #define COLLAPSED_SHIFT        18
 #define ENTRIES_SHIFT  24
 
@@ -161,7 +160,11 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
        cq_context->flags = cpu_to_be32(!!collapsed << COLLAPSED_SHIFT);
        cq_context->logsize_usrpage = cpu_to_be32(
                                                (ilog2(nent) << ENTRIES_SHIFT) | uar->index);
-       cq_context->comp_eqn        = (u8)priv->eq_table.eq[MLX4_EQ_COMP].eqn;
+       if (vector == 0) {
+               cq_context->comp_eqn        = (u8)priv->eq_table.eq[MLX4_EQ_COMP].eqn;
+       } else {
+               cq_context->comp_eqn        = (u8)priv->eq_table.eq[vector].eqn;
+       }
        cq_context->log_page_size   = (u8)(mtt->page_shift - MLX4_ICM_PAGE_SHIFT);
 
        mtt_addr = mlx4_mtt_addr(dev, mtt);
index d20d3a8..c0fc783 100644 (file)
@@ -300,14 +300,25 @@ static BOOLEAN mlx4_interrupt(
                        
                        KeInsertQueueDpc(&priv->eq_table.eq[i].dpc, NULL, NULL);
                        InterlockedCompareExchange(&dev->pdev->dpc_lock, 0, 1);
-               }
-               else {
+               } else {
                        /* re-arm the EQ for a case when interrupt comes before EQE
                        and we didn't scheduled the DPC */
                        eq_set_ci(&priv->eq_table.eq[i], 1);
                }
        }
 
+       for (i = MLX4_NUM_EQ; i <= priv->eq_table.max_extra_eqs; ++i) {
+               if (priv->eq_table.eq[i].isr) {
+                       int ret = 0;
+                       if ( next_eqe_sw(&priv->eq_table.eq[i]) ) {
+                               ret = priv->eq_table.eq[i].isr(priv->eq_table.eq[i].ctx);
+                               work |= ret;
+                       } else {
+                               eq_set_ci(&priv->eq_table.eq[i], 1);
+                       }
+               }
+       }
+
        return (BOOLEAN)work;
 }
 
@@ -708,6 +719,68 @@ err_out_free:
        return err;
 }
 
+
+int mlx4_add_eq(struct mlx4_dev *dev, int nent,
+                         u8 intr, PISR_FUNC func, PVOID func_context ,
+                         u8* p_eq_num, struct mlx4_eq ** p_eq)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       int err;
+       u8 i, new_eq = 0;
+
+    UNREFERENCED_PARAMETER(intr);
+       
+       for (i = MLX4_NUM_EQ; i < MLX4_NUM_EQ + MLX4_MAX_EXTRA_EQS ; i++) {
+               if(priv->eq_table.eq[MLX4_NUM_EQ].isr == NULL) {
+                       new_eq = i;
+                       break;
+               }
+       }
+       if (new_eq == 0)
+               return -ENOMEM;
+
+       err = mlx4_create_eq(dev, nent,
+                            (dev->flags & MLX4_FLAG_MSI_X) ? MLX4_EQ_COMP : 0,
+                            &priv->eq_table.eq[new_eq]);
+       if (err)
+               return err;
+
+       *p_eq = &priv->eq_table.eq[new_eq ];
+       *p_eq_num = new_eq;
+       priv->eq_table.eq[new_eq].isr = func;
+       priv->eq_table.eq[new_eq].ctx = func_context;
+       priv->eq_table.max_extra_eqs = max(priv->eq_table.max_extra_eqs, new_eq);
+       return 0;
+}
+
+void mlx4_remove_eq(struct mlx4_dev *dev, u8 eq_num)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       int err;
+       struct mlx4_eq_table *eq_table = &mlx4_priv(dev)->eq_table;
+
+       priv->eq_table.eq[eq_num].isr = NULL;
+       priv->eq_table.eq[eq_num].ctx = NULL;
+
+       if (priv->eq_table.max_extra_eqs == eq_num)
+               priv->eq_table.max_extra_eqs--;
+
+       mlx4_free_eq(dev, &priv->eq_table.eq[eq_num]);
+
+
+       if (eq_table->have_irq) {
+               free_irq(dev->pdev->int_obj);
+
+
+               err = request_irq( dev, 
+                       dev->pdev->int_info.u.Interrupt.Vector,
+                       mlx4_interrupt, dev, 
+                       mlx4_dpc, &priv->eq_table.eq[0],
+                       &dev->pdev->int_obj );
+               // BUGBUG: how should the error be propogated ?
+       }
+}
+
 void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
index ea4035c..051379b 100644 (file)
@@ -41,6 +41,8 @@
 #include "l2w.h"
 #include "device.h"
 #include "doorbell.h"
+#include "bus_intf.h"
+
 
 #define DRV_NAME       "mlx4_net"
 #define PFX            DRV_NAME ": "
@@ -69,7 +71,7 @@ enum mlx4_port_type {
 
 #pragma warning(disable:4201) // nameless struct/union
 typedef struct _GLOBALS {
-       BUS_WMI_STD_DATA;
+       BUS_WMI_STD_DATA bwsd;
 
        int mod_num_qp;
        int mod_rdmarc_per_qp;
@@ -110,6 +112,8 @@ enum {
        MLX4_NUM_EQ
 };
 
+#define MLX4_MAX_EXTRA_EQS 5
+
 enum {
        MLX4_NUM_PDS            = 1 << 15
 };
@@ -173,8 +177,9 @@ struct mlx4_eq {
        KDPC            dpc;            /* DPC routine */
        spinlock_t      lock;           /* spinlock for simult DPCs */
        int                     eq_ix;          /* EQ index - 0..MLX4_NUM_EQ */
-       BOOLEAN (*isr)(int,void*);      /* isr */
+       BOOLEAN (*isr)(void*);  /* isr */
        void *          ctx;            /* isr ctx */
+       USHORT eq_no_progress;  /* used to look for stacked card */
 };
 
 struct mlx4_profile {
@@ -239,13 +244,14 @@ struct mlx4_eq_table {
        void __iomem           *clr_int;
        u8 __iomem             *uar_map[(MLX4_NUM_EQ + 6) / 4];
        u32                     clr_mask;
-       struct mlx4_eq          eq[MLX4_NUM_EQ];
+       struct mlx4_eq          eq[MLX4_NUM_EQ + MLX4_MAX_EXTRA_EQS];
        u64                     icm_virt;
        dma_addr_t      icm_page;
        dma_addr_t              icm_dma;
        struct mlx4_icm_table   cmpt_table;
        int                     have_irq;
        u8                      inta_pin;
+       u8                                              max_extra_eqs;
 };
 
 struct mlx4_srq_table {
@@ -433,4 +439,9 @@ void mlx4_remove_one(struct pci_dev *pdev);
 #define ETH_FCS_LEN    4               /* Frame Check Sequence Length   */
 #define ETH_HLEN 14
 
+int mlx4_add_eq(struct mlx4_dev *dev, int nent,
+                         u8 intr, PISR_FUNC func,PVOID func_context ,
+                         u8* p_eq_num, struct mlx4_eq ** p_eq);
+
+void mlx4_remove_eq(struct mlx4_dev *dev, u8 eq_num);
 #endif /* MLX4_H */
index e55a20d..cae7adf 100644 (file)
@@ -25,7 +25,7 @@ Notes:
 \r
 #define MTNIC_MAX_PORTS     2\r
 \r
-#define MAX_PORT_SIZE 120000\r
+#define MAX_PORT_SIZE 250000\r
 #define MXE_INTERFACE_VERSION  2\r
 \r
 enum mtnic_state {\r
@@ -37,26 +37,24 @@ enum mtnic_state {
 \r
 typedef struct {\r
     enum mtnic_state     state;\r
-//    LONG            fPortStateScheuled;\r
-//    KDPC            PortStateDpc;\r
     NDIS_WORK_ITEM  PortStateWorkItem;\r
     NDIS_WORK_ITEM  ResetWorkItem;\r
     KEVENT          ConfigChangeEvent; \r
-    NDIS_SPIN_LOCK  DoorBellLock; // Used only on 32 bits systems\r
     KTIMER          HeardBeatTimer;   \r
     LONG            ResetCount;\r
 \r
     // Objects that are needed in order to work with the hw\r
-//    struct mlx4_dev        *dev;\r
 \r
     u32                     priv_pdn;\r
     struct mlx4_uar         priv_uar;\r
     void __iomem            *uar_map;\r
     struct mlx4_mr          mr;\r
     spinlock_t              uar_lock;\r
+\r
+    struct mlx4_eq *        eq;\r
+    u8                      eq_number;\r
 } NicData_t;\r
 \r
-//typedef struct _VipBusIfc\r
 struct VipBusIfc\r
 {\r
     PVOID           Context;\r
@@ -64,9 +62,9 @@ struct VipBusIfc
     ULONG           ulAllocatePortObjSize;\r
     NicData_t       NicData;\r
 #ifdef _WIN64   \r
-//    UCHAR   pad[0x8];\r
+    UCHAR   pad[0x8];\r
 #else\r
-//    UCHAR   pad[0x8];    \r
+    UCHAR   pad[0x8];    \r
 #endif    \r
 #ifdef MTNIC\r
     C_ASSERT(MAX_PORT_SIZE >= sizeof(struct _MP_PORT));\r
@@ -76,7 +74,7 @@ struct VipBusIfc
 #endif    \r
 };\r
 \r
-//??????????????????C_ASSERT((FIELD_OFFSET(struct VipBusIfc, ports) % 16) == 0);\r
-//??????????\r
+C_ASSERT((FIELD_OFFSET(struct VipBusIfc, ports) % 16) == 0);\r
+\r
 \r
 \r