\r
TARGETLIBS= \\r
$(DDK_LIB_PATH)\ntstrsafe.lib \\r
- $(TARGETPATH)\*\complib.lib\r
- \r
+ $(TARGETPATH)\*\complib.lib \r
\r
!IFDEF ENABLE_EVENT_TRACING\r
\r
unsigned long flags;
int ret = 0;
+ if (mlx4_is_barred(device->dma_device))
+ return -EFAULT;
+
if (port_num < start_port(device) || port_num > end_port(device))
return -EINVAL;
int p, i;
int ret = -ENOENT;
+ if (mlx4_is_barred(device->dma_device))
+ return -EFAULT;
+
*port_num = (u8)-1;
if (index)
*index = (u16)-1;
unsigned long flags;
int ret = 0;
+ if (mlx4_is_barred(device->dma_device))
+ return -EFAULT;
+
if (port_num < start_port(device) || port_num > end_port(device))
return -EINVAL;
int i;
int ret = -ENOENT;
+ if (mlx4_is_barred(device->dma_device))
+ return -EFAULT;
+
if (port_num < start_port(device) || port_num > end_port(device))
return -EINVAL;
}
INIT_IB_EVENT_HANDLER(&device->cache.event_handler,
- device, ib_cache_event, NULL);
+ device, ib_cache_event, NULL, NULL, 0);
if (ib_register_event_handler(&device->cache.event_handler))
goto err_cache;
return status;\r
}\r
\r
+void fix_bus_ifc(struct pci_dev *pdev)\r
+{\r
+ PFDO_DEVICE_DATA p_fdo;\r
+\r
+ p_fdo = CONTAINING_RECORD(pdev, FDO_DEVICE_DATA, pci_dev);\r
+ p_fdo->bus_ib_ifc.p_ibdev = p_fdo->pci_dev.ib_dev;\r
+ p_fdo->bus_ib_ifc.pmlx4_dev = to_mdev(p_fdo->pci_dev.ib_dev)->dev;\r
+ p_fdo->bus_ib_ifc.is_livefish = mlx4_is_livefish(p_fdo->pci_dev.dev);\r
+}\r
+\r
NTSTATUS\r
EvtReleaseHardware(\r
IN WDFDEVICE Device,\r
// "Ports L2 type (ib/eth/auto, entry per port, comma seperated, default ib for all)"\r
DECLARE_CONST_UNICODE_STRING(PortType, L"PortType");\r
\r
- \r
+\r
ULONG value;\r
WDFKEY hKey = NULL;\r
NTSTATUS status = STATUS_SUCCESS;\r
else\r
g.mod_interrupt_from_first = 1;\r
\r
+\r
uvalue.Buffer = uvalue_data;\r
uvalue.MaximumLength = MAX_UVALUE;\r
uvalue.Length = 0;\r
MLX4_BUS_IB_INTERFACE bus_ib_ifc;\r
int children_created;\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
//\r
%MT26428.DeviceDesc%=MLX4BUS.DDInstall, PCI\VEN_15B3&DEV_673c\r
%MT00401.DeviceDesc%=MLX4BUS.DDInstall, PCI\VEN_15B3&DEV_0191\r
\r
-[MLX4BUS.DDInstall.ntx86.hw]\r
-AddReg = MLX4BUS.HwReg\r
-\r
-[MLX4BUS.DDInstall.ntamd64.hw]\r
-AddReg = MLX4BUS.HwReg\r
-\r
-[MLX4BUS.DDInstall.ntia64.hw]\r
-AddReg = MLX4BUS.HwReg\r
-\r
-[MLX4BUS.HwReg]\r
-HKR,"Interrupt Management", 0x00000010\r
-HKR,"Interrupt Management\MessageSignaledInterruptProperties",0x00000010\r
-\r
-; MSI/MSI-X support\r
-HKR,"Interrupt Management\MessageSignaledInterruptProperties",MSISupported,0x00010001,0\r
-HKR,"Interrupt Management\MessageSignaledInterruptProperties",MessageNumberLimit,0x00010001,8\r
-HKR,"Interrupt Management\Affinity Policy",0x00000010\r
-\r
-; AssignmentSetOverride - processors KAFFINITY mask \r
-HKR,"Interrupt Management\Affinity Policy",AssignmentSetOverride,0x00000001,0x0\r
-\r
-; IrqPolicyMachineDefault (0) - use default policy for the computer\r
-; IrqPolicyAllCloseProcessors (1) - connect interrupts to all processors of the near NUMA node\r
-; IrqPolicyOneCloseProcessor (2) - connect interrupts to one processor\r
-; IrqPolicyAllProcessorsInMachine (3) - connect interrupts to all processors in the machine\r
-; IrqPolicySpecifiedProcessors (4) - connects interrupts according to AssignmentSetOverride\r
-HKR,"Interrupt Management\Affinity Policy",DevicePolicy,0x00010001,0x0\r
-\r
-; IrqArbPriorityUndefined (0) - no interrupt priority policy. \r
-; IrqArbPriorityLow (1) - device can tolerate low IRQL\r
-; IrqArbPriorityNormal (2) - device expects normal interrupt latencies\r
-; IrqArbPriorityHigh (3) - device requires the lowest possible interrupt latency\r
-HKR,"Interrupt Management\Affinity Policy",DevicePriority,0x00010001,0x0\r
-\r
[MLX4BUS.DDInstall.ntx86]\r
CopyFiles = MLX4BUS.CopyFiles\r
\r
\r
#define MAX_ID_LEN 80\r
\r
+NTSTATUS\r
+EvtDeviceProcessQueryInterfaceRequest(\r
+ IN WDFDEVICE Device,\r
+ IN LPGUID InterfaceType,\r
+ IN OUT PINTERFACE ExposedInterface,\r
+ IN OUT PVOID ExposedInterfaceSpecificData\r
+ )\r
+{\r
+ PPDO_DEVICE_DATA p_pdo = PdoGetData(Device);\r
+ PFDO_DEVICE_DATA p_fdo = p_pdo->p_fdo;\r
+ PMLX4_BUS_IB_INTERFACE p_ib_ifc = (PMLX4_BUS_IB_INTERFACE)ExposedInterface;\r
+\r
+ UNUSED_PARAM(InterfaceType);\r
+ UNUSED_PARAM(ExposedInterfaceSpecificData);\r
+\r
+ p_ib_ifc->p_ibdev = p_fdo->bus_ib_ifc.p_ibdev;\r
+ p_ib_ifc->pmlx4_dev = p_fdo->bus_ib_ifc.pmlx4_dev;\r
+ p_ib_ifc->is_livefish = p_fdo->bus_ib_ifc.is_livefish;\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
NTSTATUS\r
create_pdo(\r
__in WDFDEVICE Device,\r
\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
- p_fdo->bus_ib_ifc.unregister_interface = mlx4_unregister_interface;\r
p_fdo->bus_ib_ifc.mlx4_interface.mlx4_pd_alloc = mlx4_pd_alloc;\r
p_fdo->bus_ib_ifc.mlx4_interface.mlx4_pd_free = mlx4_pd_free;\r
p_fdo->bus_ib_ifc.mlx4_interface.mlx4_uar_alloc = mlx4_uar_alloc;\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
- p_fdo->bus_ib_ifc.mlx4_interface.mlx4_register_ev_cb = ib_register_event_handler;\r
- p_fdo->bus_ib_ifc.mlx4_interface.mlx4_unregister_ev_cb = ib_unregister_event_handler;\r
+ p_fdo->bus_ib_ifc.mlx4_interface.mlx4_register_ev_cb = mlx4_reset_cb_register;\r
+ p_fdo->bus_ib_ifc.mlx4_interface.mlx4_unregister_ev_cb = mlx4_reset_cb_unregister;\r
+ p_fdo->bus_ib_ifc.mlx4_interface.mlx4_reset_request = mlx4_reset_request;\r
+ p_fdo->bus_ib_ifc.mlx4_interface.mlx4_reset_execute = mlx4_reset_execute;\r
\r
//\r
// Create a custom interface so that other drivers can\r
\r
WDF_QUERY_INTERFACE_CONFIG_INIT( &p_pdo->qiMlx4Bus,\r
(PINTERFACE) &p_fdo->bus_ib_ifc,\r
- &MLX4_BUS_IB_INTERFACE_GUID, NULL);\r
+ &MLX4_BUS_IB_INTERFACE_GUID, EvtDeviceProcessQueryInterfaceRequest);\r
\r
status = WdfDeviceAddQueryInterface( hChild, &p_pdo->qiMlx4Bus );\r
if (!NT_SUCCESS(status))\r
(PINTERFACE) &p_fdo->pci_dev.bus_pci_ifc,\r
&GUID_BUS_INTERFACE_STANDARD, NULL);\r
\r
+ // TODO: Soft Reset - how tobar getting interface during RESET_IN_PROGRESS\r
+ // maybe - using EvtDeviceProcessQueryInterfaceRequest\r
status = WdfDeviceAddQueryInterface( hChild, &p_pdo->qiPciBus );\r
if (!NT_SUCCESS(status))\r
goto Cleanup;\r
struct mlx4_dev *dev = to_mdev(pd->device)->dev;
struct mlx4_ib_ah *ah;
+ if (mlx4_is_barred(pd->device->dma_device))
+ return ERR_PTR(-EFAULT);
+
ah = kmalloc(sizeof *ah, GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
{
struct mlx4_ib_ah *ah = to_mah(ibah);
+ if (mlx4_is_barred(ibah->device->dma_device))
+ return -EFAULT;
+
memset(ah_attr, 0, sizeof *ah_attr);
ah_attr->dlid = be16_to_cpu(ah->av.dlid);
ah_attr->sl = (u8)(be32_to_cpu(ah->av.sl_tclass_flowlabel) >> 28);
struct mlx4_av *av = &to_mah(ibah)->av;
struct mlx4_dev *dev = to_mdev(ibah->pd->device)->dev;
+ if (mlx4_is_barred(dev))
+ return -EFAULT;
+
// taken from mthca_create_av
av->port_pd = cpu_to_be32(to_mpd(ibah->pd)->pdn | (ah_attr->port_num << 24));
av->g_slid = ah_attr->src_path_bits;
struct mlx4_cq_context *context;\r
int err;\r
\r
+ if (mlx4_is_barred(dev->dev))\r
+ return -EFAULT;\r
+\r
context = kzalloc(sizeof *context, GFP_KERNEL);\r
if (!context)\r
return -ENOMEM;\r
\r
UNUSED_PARAM(vector);\r
\r
+ if (mlx4_is_barred(ibdev->dma_device))\r
+ return ERR_PTR(-EFAULT);\r
+\r
if (entries < 1 || entries > dev->dev->caps.max_cqes)\r
return ERR_PTR(-EINVAL);\r
\r
\r
int mlx4_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)\r
{\r
- mlx4_cq_arm(&to_mcq(ibcq)->mcq,\r
+ if (!mlx4_is_barred(ibcq->device->dma_device))\r
+ mlx4_cq_arm(&to_mcq(ibcq)->mcq,\r
(flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?\r
MLX4_CQ_DB_REQ_NOT_SOL : MLX4_CQ_DB_REQ_NOT,\r
to_mdev(ibcq->device)->uar_map,\r
u16 slid;
int err;
+ if (mlx4_is_barred(ibdev->dma_device))
+ return -EFAULT;
+
slid = in_wc ? be16_to_cpu(in_wc->recv.ud.remote_lid) : be16_to_cpu(XIB_LID_PERMISSIVE);
if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && slid == 0) {
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
+ if (mlx4_is_barred(ibdev->dma_device))
+ return -EFAULT;
+
in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
if (!in_mad || !out_mad)
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
+ if (mlx4_is_barred(ibdev->dma_device))
+ return -EFAULT;
+
in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
if (!in_mad || !out_mad)
__be64 subnet_prefix;
int err = -ENOMEM;
+ if (mlx4_is_barred(ibdev->dma_device))
+ return -EFAULT;
+
in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
if (!in_mad || !out_mad)
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
+ if (mlx4_is_barred(ibdev->dma_device))
+ return -EFAULT;
+
in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
if (!in_mad || !out_mad)
static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask,
struct ib_device_modify *props)
{
+ if (mlx4_is_barred(ibdev->dma_device))
+ return -EFAULT;
+
if (mask & ~IB_DEVICE_MODIFY_NODE_DESC)
return -EOPNOTSUPP;
u32 cap_mask;
int err;
+ if (mlx4_is_barred(ibdev->dma_device))
+ return -EFAULT;
+
mutex_lock(&to_mdev(ibdev)->cap_mask_mutex);
err = mlx4_ib_query_port(ibdev, port, &attr);
struct mlx4_ib_alloc_ucontext_resp resp;
int err;
+ if (mlx4_is_barred(ibdev->dma_device))
+ return ERR_PTR(-EFAULT);
+
resp.qp_tab_size = dev->dev->caps.num_qps;
resp.bf_reg_size = (__u16)dev->dev->caps.bf_reg_size;
resp.bf_regs_per_page = (__u16)dev->dev->caps.bf_regs_per_page;
struct mlx4_ib_pd *pd;
int err;
+ if (mlx4_is_barred(ibdev->dma_device))
+ return ERR_PTR(-EFAULT);
+
pd = kmalloc(sizeof *pd, GFP_KERNEL);
if (!pd)
return ERR_PTR(-ENOMEM);
static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
{
UNUSED_PARAM(lid);
+ if (mlx4_is_barred(ibqp->device->dma_device))
+ return -EFAULT;
return mlx4_multicast_attach(to_mdev(ibqp->device)->dev,
&to_mqp(ibqp)->mqp, gid->raw);
}
static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
{
UNUSED_PARAM(lid);
+ if (mlx4_is_barred(ibqp->device->dma_device))
+ return -EFAULT;
return mlx4_multicast_detach(to_mdev(ibqp->device)->dev,
&to_mqp(ibqp)->mqp, gid->raw);
}
struct mlx4_ib_mr *mr;
int err;
+ if (mlx4_is_barred(pd->device->dma_device))
+ return ERR_PTR(-EFAULT);
+
mr = kmalloc(sizeof *mr, GFP_KERNEL);
if (!mr)
return ERR_PTR(-ENOMEM);
int n;
UNUSED_PARAM(udata);
+
+ if (mlx4_is_barred(pd->device->dma_device))
+ return ERR_PTR(-EFAULT);
mr = kmalloc(sizeof *mr, GFP_KERNEL);
if (!mr)
struct mlx4_ib_fmr *fmr;
int err = -ENOMEM;
+ if (mlx4_is_barred(pd->device->dma_device))
+ return ERR_PTR(-EFAULT);
+
fmr = kmalloc(sizeof *fmr, GFP_KERNEL);
if (!fmr)
return ERR_PTR(-ENOMEM);
struct mlx4_ib_fmr *ifmr = to_mfmr(ibfmr);
struct mlx4_ib_dev *dev = to_mdev(ifmr->ibfmr.device);
+ if (mlx4_is_barred(ifmr->ibfmr.device->dma_device))
+ return -EFAULT;
+
return mlx4_map_phys_fmr(dev->dev, &ifmr->mfmr, page_list, npages, iova,
&ifmr->ibfmr.lkey, &ifmr->ibfmr.rkey);
}
int mlx4_ib_unmap_fmr(struct list_head *fmr_list)
{
struct ib_fmr *ibfmr;
- int err;
+ int err = 0;
struct mlx4_dev *mdev = NULL;
list_for_each_entry(ibfmr, fmr_list, list, struct ib_fmr) {
*/
wmb();
- err = mlx4_SYNC_TPT(mdev);
+ if (!mlx4_is_barred(mdev))
+ err = mlx4_SYNC_TPT(mdev);
if (err)
printk(KERN_WARNING "mlx4_ib: SYNC_TPT error %d when "
"unmapping FMRs\n", err);
struct mlx4_ib_qp *qp;\r
int err;\r
\r
+ if (mlx4_is_barred(pd->device->dma_device))\r
+ return ERR_PTR(-EFAULT);\r
+\r
switch (init_attr->qp_type) {\r
case IB_QPT_RC:\r
case IB_QPT_UC:\r
struct mlx4_ib_dev *dev = to_mdev(qp->device);\r
struct mlx4_ib_qp *mqp = to_mqp(qp);\r
\r
- if (is_qp0(dev, mqp))\r
+ if (!mlx4_is_barred(dev->dev) && is_qp0(dev, mqp))\r
mlx4_CLOSE_PORT(dev->dev, mqp->port);\r
\r
destroy_qp_common(dev, mqp, !!qp->pd->p_uctx);\r
\r
UNUSED_PARAM(udata);\r
\r
+ if (mlx4_is_barred(dev->dev))\r
+ return -EFAULT; \r
+\r
mutex_lock(&qp->mutex);\r
\r
cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;\r
int size;\r
int i;\r
\r
+ if (mlx4_is_barred(ibqp->device->dma_device))\r
+ return -EFAULT;\r
+\r
spin_lock_irqsave(&qp->sq.lock, &flags);\r
\r
ind = qp->sq.head;\r
int ind;\r
int i;\r
\r
+ if (mlx4_is_barred(ibqp->device->dma_device))\r
+ return -EFAULT;\r
+\r
spin_lock_irqsave(&qp->rq.lock, &flags);\r
\r
ind = qp->rq.head & (qp->rq.wqe_cnt - 1);\r
\r
UNUSED_PARAM(qp_attr_mask);\r
\r
+ if (mlx4_is_barred(dev->dev))\r
+ return -EFAULT;\r
+ \r
if (qp->state == XIB_QPS_RESET) {\r
qp_attr->qp_state = XIB_QPS_RESET;\r
goto done;\r
u32 cqn = 0;\r
u16 xrcd = 0;\r
\r
+ if (mlx4_is_barred(pd->device->dma_device))\r
+ return ERR_PTR(-EFAULT);\r
+\r
/* Sanity check SRQ size before proceeding */\r
if ((int)init_attr->attr.max_wr >= dev->dev->caps.max_srq_wqes ||\r
(int)init_attr->attr.max_sge > dev->dev->caps.max_srq_sge)\r
int ret;\r
\r
UNUSED_PARAM(udata);\r
+\r
+ if (mlx4_is_barred(ibsrq->device->dma_device))\r
+ return -EFAULT;\r
\r
/* We don't support resizing SRQs (yet?) */\r
if (attr_mask & XIB_SRQ_MAX_WR)\r
int ret;\r
int limit_watermark;\r
\r
+ if (mlx4_is_barred(ibsrq->device->dma_device))\r
+ return -EFAULT;\r
+\r
ret = mlx4_srq_query(dev->dev, &srq->msrq, &limit_watermark);\r
if (ret)\r
return ret;\r
struct mlx4_ib_dev *dev = to_mdev(srq->device);\r
struct mlx4_ib_srq *msrq = to_msrq(srq);\r
\r
- mlx4_srq_invalidate(dev->dev, &msrq->msrq);\r
+ if (!mlx4_is_barred(dev->dev))\r
+ mlx4_srq_invalidate(dev->dev, &msrq->msrq);\r
mlx4_srq_remove(dev->dev, &msrq->msrq);\r
\r
mlx4_srq_free(dev->dev, &msrq->msrq);\r
int nreq;\r
int i;\r
\r
+ if (mlx4_is_barred(ibsrq->device->dma_device))\r
+ return -EFAULT;\r
+\r
spin_lock_irqsave(&srq->lock, &flags);\r
\r
for (nreq = 0; wr; ++nreq, wr = wr->p_next) {\r
typedef int (*MLX4_REGISTER_EVENT_HANDLER) (struct ib_event_handler *event_handler);
typedef int (*MLX4_UNREGISTER_EVENT_HANDLER)(struct ib_event_handler *event_handler);
+typedef int (*MLX4_RESET_REQUEST) (struct ib_event_handler *event_handler);
+typedef int (*MLX4_RESET_EXECUTE) (struct ib_event_handler *event_handler);
struct mlx4_interface_ex {
MLX4_PD_ALLOC mlx4_pd_alloc;
MLX4_REGISTER_EVENT_HANDLER mlx4_register_ev_cb;
MLX4_UNREGISTER_EVENT_HANDLER mlx4_unregister_ev_cb;
+ MLX4_RESET_REQUEST mlx4_reset_request;
+ MLX4_RESET_EXECUTE mlx4_reset_execute;
};
struct mlx4_dev * pmlx4_dev;
struct mlx4_interface_ex mlx4_interface;
int is_livefish;
- MLX4_REGISTER_INTERFACE register_interface;
- MLX4_UNREGISTER_INTERFACE unregister_interface;
u8 port_id;
struct VipBusIfc *pVipBusIfc;
enum {
MLX4_FLAG_MSI_X = 1 << 0,
MLX4_FLAG_OLD_PORT_CMDS = 1 << 1,
- MLX4_FLAG_LIVEFISH = 1 << 10
+ MLX4_FLAG_LIVEFISH = 1 << 10,
+ MLX4_FLAG_RESET_CLIENT = 1 << 11,
+ MLX4_FLAG_RESET_DRIVER = 1 << 12,
+ MLX4_FLAG_RESET_STARTED = 1 << 13
};
enum {
IB_EVENT_LID_CHANGE = IB_AE_UNKNOWN + 1,\r
IB_EVENT_PKEY_CHANGE,\r
IB_EVENT_SM_CHANGE,\r
- IB_EVENT_CLIENT_REREGISTER\r
+ IB_EVENT_CLIENT_REREGISTER,\r
+ IB_EVENT_RESET_DRIVER, // device will be reset upon fatal error\r
+ IB_EVENT_RESET_CLIENT, // device will be upon client request\r
+ IB_EVENT_RESET_END // device has been reset \r
};\r
\r
struct ib_event {\r
} element;\r
enum ib_event_type event;\r
struct ib_event_ex x;\r
- };\r
+};\r
+\r
+enum ib_event_handler_flags {\r
+ IB_IVH_RESET_CB = (1 << 0),\r
+ IB_IVH_NOTIFIED = (1 << 1),\r
+ IB_IVH_RESET_READY = (1 << 2)\r
+};\r
+\r
\r
struct ib_event_handler {\r
struct ib_device *device;\r
void (*handler)(struct ib_event_handler *, struct ib_event *);\r
- void * ctx;\r
struct list_head list;\r
+ void * ctx;\r
+ void * rsrv_ptr;\r
+ u32 flags;\r
};\r
\r
-#define INIT_IB_EVENT_HANDLER(_ptr, _device, _handler, _ctx) \\r
+#define INIT_IB_EVENT_HANDLER(_ptr, _device, _handler, _ctx, _rptr, _flags) \\r
{ \\r
(_ptr)->device = _device; \\r
(_ptr)->handler = _handler; \\r
+ INIT_LIST_HEAD(&(_ptr)->list); \\r
(_ptr)->ctx = _ctx; \\r
- INIT_LIST_HEAD(&(_ptr)->list); \\r
+ (_ptr)->rsrv_ptr = _rptr; \\r
+ (_ptr)->flags = _flags; \\r
}\r
\r
struct ib_global_route {\r
{
int err;
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
err = mlx4_db_alloc(dev, &wqres->db, 1);
if (err)
return err;
// "Reset device on internal errors if non-zero (default 1)")
int g_internal_err_reset = 1;
+static void dispatch_event(struct ib_device *ibdev, enum ib_event_type type)
+{
+ unsigned long flags;
+ struct ib_event event;
+ struct ib_event_handler *handler;
+
+ event.device = ibdev;
+ event.event = type;
+
+ spin_lock_irqsave(&ibdev->event_handler_lock, &flags);
+
+ list_for_each_entry(handler, &ibdev->event_handler_list, list, struct ib_event_handler)
+ {
+ // notify only those, that are not notified
+ if ( handler->flags & IB_IVH_RESET_CB )
+ if ( !(handler->flags & IB_IVH_NOTIFIED) ) {
+ handler->flags |= IB_IVH_NOTIFIED;
+ handler->handler(handler, &event);
+ }
+ }
+
+ spin_unlock_irqrestore(&ibdev->event_handler_lock, flags);
+}
+
+/**
+ * get_event_handlers - return list of handlers of the device
+ * @device:device
+ * @tlist:list
+ *
+ * get_event_handlers() remove all the device event handlers and put them in 'tlist'
+ */
+static void get_event_handlers(struct ib_device *device, struct list_head *tlist)
+{
+ unsigned long flags;
+ struct ib_event_handler *handler, *thandler;
+
+ spin_lock_irqsave(&device->event_handler_lock, &flags);
+
+ list_for_each_entry_safe(handler, thandler, &device->event_handler_list,
+ list, struct ib_event_handler, struct ib_event_handler)
+ {
+ // take out only reset callbacks
+ if ( handler->flags & IB_IVH_RESET_CB ) {
+ list_del( &handler->list );
+ list_add_tail( &handler->list, tlist );
+ }
+ }
+
+ spin_unlock_irqrestore(&device->event_handler_lock, flags);
+}
+
+
static void dump_err_buf(struct mlx4_dev *dev)
{
struct mlx4_priv *priv = mlx4_priv(dev);
mlx4_dispatch_event(dev, MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR, 0, 0);
+ // bar the device
+ dev->flags |= MLX4_FLAG_RESET_DRIVER;
+
+ // notify the clients
+ dispatch_event(dev->pdev->ib_dev, IB_EVENT_RESET_DRIVER);
+
if (g_internal_err_reset) {
PIO_WORKITEM catas_work = IoAllocateWorkItem( dev->pdev->p_self_do );
struct mlx4_priv *priv = mlx4_priv(dev);
spin_lock_irq(&catas_lock);
+ if (priv->catas_err.stop) {
+ spin_unlock_irq(&catas_lock);
+ return;
+ }
priv->catas_err.stop = 1;
spin_unlock_irq(&catas_lock);
spin_unlock_irq(&catas_lock);
}
+static int wait4reset(struct ib_event_handler *event_handler)
+{
+ int n_not_ready = 0;
+ unsigned long flags;
+ struct ib_event_handler *handler;
+ struct ib_device *ibdev = event_handler->device;
+
+ spin_lock_irqsave(&ibdev->event_handler_lock, &flags);
+
+ // mark this handler (=client) reset-ready
+ event_handler->flags |= IB_IVH_RESET_READY;
+
+ // check the number of still not ready client
+
+ list_for_each_entry(handler, &ibdev->event_handler_list, list, struct ib_event_handler)
+ if ( handler->flags & IB_IVH_RESET_CB )
+ if ( !(handler->flags & IB_IVH_RESET_READY) )
+ ++n_not_ready;
+
+ spin_unlock_irqrestore(&ibdev->event_handler_lock, flags);
+
+ return n_not_ready;
+}
+
+int mlx4_reset_execute( struct ib_event_handler *event_handler )
+{
+ int err;
+ struct ib_event event;
+ struct list_head tlist;
+ struct ib_event_handler *handler, *thandler;
+ struct ib_device *ibdev = event_handler->device;
+ struct pci_dev *pdev = ibdev->dma_device->pdev;
+
+ // mark client as "ready for reset" and check whether we can do reset
+ if (wait4reset(event_handler))
+ return 0;
+
+ // fully bar the device
+ ibdev->dma_device->flags |= MLX4_FLAG_RESET_STARTED;
+
+ // get old handler list
+ INIT_LIST_HEAD(&tlist);
+ get_event_handlers(ibdev, &tlist);
+
+ // restart the device
+ err = mlx4_restart_one(pdev);
+
+ // recreate interfaces
+ fix_bus_ifc(pdev);
+
+ // notify the clients
+ event.event = IB_EVENT_RESET_END;
+ list_for_each_entry_safe(handler, thandler, &tlist,
+ list, struct ib_event_handler, struct ib_event_handler)
+ {
+ // because 'handler' will be re-registered during the next call
+ list_del( &handler->list );
+ handler->handler(handler, &event);
+ }
+
+ return err;
+}
+
+static void
+card_reset_wi(
+ IN DEVICE_OBJECT* p_dev_obj,
+ IN struct ib_event_handler * event_handler )
+{
+ NTSTATUS status;
+ struct ib_device *ibdev = event_handler->device;
+ struct mlx4_dev *dev = ibdev->dma_device;
+
+ UNUSED_PARAM(p_dev_obj);
+ IoFreeWorkItem( event_handler->rsrv_ptr );
+
+ // reset the card
+ mlx4_stop_catas_poll( dev );
+ status = mlx4_reset( dev );
+ if ( !NT_SUCCESS( status ) )
+ mlx4_err( dev, "Failed to reset HCA, aborting. (status %#x)\n", status );
+
+ // notify the clients
+ dispatch_event(ibdev, IB_EVENT_RESET_CLIENT);
+}
+
+int mlx4_reset_request( struct ib_event_handler *event_handler )
+{
+ struct ib_device *ibdev = event_handler->device;
+ struct mlx4_dev *dev = ibdev->dma_device;
+
+ // set device to RESET_PENDING mode
+ if (!mlx4_is_barred(dev)) {
+ PIO_WORKITEM reset_work;
+
+ // bar the device
+ dev->flags |= MLX4_FLAG_RESET_CLIENT;
+
+ // delay reset to a system thread
+ // to allow for end of operations that are in progress
+ reset_work = IoAllocateWorkItem( dev->pdev->p_self_do );
+ if (!reset_work)
+ return -EFAULT;
+ event_handler->rsrv_ptr = reset_work;
+ IoQueueWorkItem( reset_work, card_reset_wi, DelayedWorkQueue, event_handler );
+ }
+
+ return 0;
+}
+
+int mlx4_reset_cb_register( struct ib_event_handler *event_handler )
+{
+ if (mlx4_is_in_reset(event_handler->device->dma_device))
+ return -EBUSY;
+
+ return ib_register_event_handler(event_handler);
+}
+
+int mlx4_reset_cb_unregister( struct ib_event_handler *event_handler )
+{
+ return ib_unregister_event_handler(event_handler);
+}
+
{
struct mlx4_cmd_mailbox *mailbox;
+ if ( mlx4_is_barred(dev) )
+ return ERR_PTR(-EFAULT);
+
mailbox = kmalloc(sizeof *mailbox, GFP_KERNEL);
if (!mailbox)
return ERR_PTR(-ENOMEM);
int imlx4_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param, int out_is_imm,
u32 in_modifier, u8 op_modifier, u16 op, unsigned long timeout)
{
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
return __mlx4_cmd(dev, in_param, out_param, out_is_imm, in_modifier,
op_modifier, op, timeout);
}
#define COLLAPSED_SHIFT 18
#define ENTRIES_SHIFT 24
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
cq->cqn = mlx4_bitmap_alloc(&cq_table->bitmap);
if (cq->cqn == -1)
return -ENOMEM;
struct mlx4_cmd_mailbox *mailbox;
int err;
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
return PTR_ERR(mailbox);
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_cq_table *cq_table = &priv->cq_table;
- int err;
+ int err = 0;
- err = mlx4_HW2SW_CQ(dev, NULL, cq->cqn);
+ if (!mlx4_is_barred(dev))
+ err = mlx4_HW2SW_CQ(dev, NULL, cq->cqn);
if (err)
mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn);
if (atomic_dec_and_test(&cq->refcount))
complete(&cq->free);
- wait_for_completion(&cq->free);
+ if (!mlx4_is_barred(dev))
+ wait_for_completion(&cq->free);
mlx4_table_put(dev, &cq_table->table, cq->cqn);
mlx4_bitmap_free(&cq_table->bitmap, cq->cqn);
UNREFERENCED_PARAMETER(intr);
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
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;
u32 flags;
u16 field;
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
#define INIT_PORT_IN_SIZE 256
#define INIT_PORT_FLAGS_OFFSET 0x00
int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port)
{
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
return mlx4_cmd(dev, 0, port, 0, MLX4_CMD_CLOSE_PORT, 1000);
}
EXPORT_SYMBOL_GPL(mlx4_CLOSE_PORT);
struct mlx4_priv *priv;
struct mlx4_dev *dev;
int err;
+ NTSTATUS status;
#ifdef FORCE_LIVEFISH
if (pdev)
* attempt a firmware command, since a boot ROM may have left
* the HCA in an undefined state.
*/
- err = mlx4_reset(dev);
- if (err) {
- mlx4_err(dev, "Failed to reset HCA, aborting.\n");
+ status = mlx4_reset(dev);
+ if ( !NT_SUCCESS( status ) ) {
+ mlx4_err(dev, "Failed to reset HCA, aborting.(status %#x)\n", status);
+ err = -EFAULT;
goto err_free_dev;
}
u8* p_eq_num, struct mlx4_eq ** p_eq);
void mlx4_remove_eq(struct mlx4_dev *dev, u8 eq_num);
+
+int mlx4_reset_execute( struct ib_event_handler *event_handler );
+
+int mlx4_reset_request( struct ib_event_handler *event_handler );
+
+int mlx4_reset_cb_register( struct ib_event_handler *event_handler );
+
+int mlx4_reset_cb_unregister( struct ib_event_handler *event_handler );
+
+void fix_bus_ifc(struct pci_dev *pdev);
+
+
+
#endif /* MLX4_H */
u32 index;
int err;
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
index = mlx4_bitmap_alloc(&priv->mr_table.mpt_bitmap);
if (index == -1)
return -ENOMEM;
struct mlx4_priv *priv = mlx4_priv(dev);
int err;
- if (mr->enabled) {
+ if (!mlx4_is_barred(dev) && mr->enabled) {
err = mlx4_HW2SW_MPT(dev, NULL,
key_to_hw_index(mr->key) &
(dev->caps.num_mpts - 1));
struct mlx4_mpt_entry *mpt_entry;
int err;
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
err = mlx4_table_get(dev, &mr_table->dmpt_table, key_to_hw_index(mr->key));
if (err)
return err;
{
struct mlx4_priv *priv = mlx4_priv(dev);
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
*pdn = mlx4_bitmap_alloc(&priv->pd_bitmap);
if (*pdn == -1)
return -ENOMEM;
int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar)
{
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
uar->index = mlx4_bitmap_alloc(&mlx4_priv(dev)->uar_table.bitmap);
if (uar->index == -1)
return -ENOMEM;
-/*
- * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-#include "mlx4.h"
-#include "cmd.h"
-
-
-void mlx4_init_mac_table(struct mlx4_dev *dev, u8 port)
-{
- struct mlx4_mac_table *table = &mlx4_priv(dev)->port[port].mac_table;
- int i;
-
- sema_init(&table->mac_sem, 1);
- for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
- table->entries[i] = 0;
- table->refs[i] = 0;
- }
- table->max = 1 << dev->caps.log_num_macs;
- table->total = 0;
-}
-
-void mlx4_init_vlan_table(struct mlx4_dev *dev, u8 port)
-{
- struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
- int i;
-
- sema_init(&table->vlan_sem, 1);
- for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
- table->entries[i] = 0;
- table->refs[i] = 0;
- }
- table->max = 1 << dev->caps.log_num_vlans;
- table->total = 0;
-}
-
-static int mlx4_SET_PORT_mac_table(struct mlx4_dev *dev, u8 port,
- __be64 *entries)
-{
- struct mlx4_cmd_mailbox *mailbox;
- u32 in_mod;
- int err;
-
- mailbox = mlx4_alloc_cmd_mailbox(dev);
- if (IS_ERR(mailbox))
- return PTR_ERR(mailbox);
-
- memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);
-
- in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;
- err = mlx4_cmd(dev, mailbox->dma.da, in_mod, 1, MLX4_CMD_SET_PORT,
- MLX4_CMD_TIME_CLASS_B);
-
- mlx4_free_cmd_mailbox(dev, mailbox);
- return err;
-}
-
-int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index)
-{
- struct mlx4_mac_table *table =
- &mlx4_priv(dev)->port[port - 1].mac_table;
- int i, err = 0;
- int free = -1;
- u64 valid = 1;
-
- mlx4_dbg(dev, "Registering mac : 0x%llx\n", mac);
- down(&table->mac_sem);
- for (i = 0; i < MLX4_MAX_MAC_NUM - 1; i++) {
- if (free < 0 && !table->refs[i]) {
- free = i;
- continue;
- }
-
- if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
- /* Mac already registered, increase refernce count */
- *index = i;
- ++table->refs[i];
- goto out;
- }
- }
- mlx4_dbg(dev, "Free mac index is %d\n", free);
-
- if (table->total == table->max) {
- /* No free mac entries */
- err = -ENOSPC;
- goto out;
- }
-
- /* Register new MAC */
- table->refs[free] = 1;
- table->entries[free] = cpu_to_be64(mac | valid << MLX4_MAC_VALID_SHIFT);
-
- err = mlx4_SET_PORT_mac_table(dev, port, table->entries);
- if (unlikely(err)) {
- mlx4_err(dev, "Failed adding mac: 0x%llx\n", mac);
- table->refs[free] = 0;
- table->entries[free] = 0;
- goto out;
- }
-
- *index = free;
- ++table->total;
-out:
- up(&table->mac_sem);
- return err;
-}
-EXPORT_SYMBOL_GPL(mlx4_register_mac);
-
-void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index)
-{
- struct mlx4_mac_table *table =
- &mlx4_priv(dev)->port[port - 1].mac_table;
-
- down(&table->mac_sem);
- if (!table->refs[index]) {
- mlx4_warn(dev, "No mac entry for index %d\n", index);
- goto out;
- }
- if (--table->refs[index]) {
- mlx4_warn(dev, "Have more references for index %d,"
- "no need to modify mac table\n", index);
- goto out;
- }
- table->entries[index] = 0;
- mlx4_SET_PORT_mac_table(dev, port, table->entries);
- --table->total;
-out:
- up(&table->mac_sem);
-}
-EXPORT_SYMBOL_GPL(mlx4_unregister_mac);
-
-static int mlx4_SET_PORT_vlan_table(struct mlx4_dev *dev, u8 port,
- __be32 *entries)
-{
- struct mlx4_cmd_mailbox *mailbox;
- u32 in_mod;
- int err;
-
- mailbox = mlx4_alloc_cmd_mailbox(dev);
- if (IS_ERR(mailbox))
- return PTR_ERR(mailbox);
-
- memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);
- in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;
- err = mlx4_cmd(dev, mailbox->dma.da, in_mod, 1, MLX4_CMD_SET_PORT,
- MLX4_CMD_TIME_CLASS_B);
-
- mlx4_free_cmd_mailbox(dev, mailbox);
-
- return err;
-}
-
-int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
-{
- struct mlx4_vlan_table *table =
- &mlx4_priv(dev)->port[port - 1].vlan_table;
- int i, err = 0;
- int free = -1;
-
- down(&table->vlan_sem);
- for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
- if (free < 0 && (table->refs[i] == 0)) {
- free = i;
- continue;
- }
-
- if (table->refs[i] &&
- (vlan == (MLX4_VLAN_MASK &
- be32_to_cpu(table->entries[i])))) {
- /* Vlan already registered, increase refernce count */
- *index = i;
- ++table->refs[i];
- goto out;
- }
- }
-
- if (table->total == table->max) {
- /* No free vlan entries */
- err = -ENOSPC;
- goto out;
- }
-
- /* Register new MAC */
- table->refs[free] = 1;
- table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);
-
- err = mlx4_SET_PORT_vlan_table(dev, port, table->entries);
- if (unlikely(err)) {
- mlx4_warn(dev, "Failed adding vlan: %u\n", vlan);
- table->refs[free] = 0;
- table->entries[free] = 0;
- goto out;
- }
-
- *index = free;
- ++table->total;
-out:
- up(&table->vlan_sem);
- return err;
-}
-EXPORT_SYMBOL_GPL(mlx4_register_vlan);
-
-void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
-{
- struct mlx4_vlan_table *table =
- &mlx4_priv(dev)->port[port - 1].vlan_table;
-
- down(&table->vlan_sem);
- if (!table->refs[index]) {
- mlx4_warn(dev, "No vlan entry for index %d\n", index);
- goto out;
- }
- if (--table->refs[index]) {
- mlx4_dbg(dev, "Have more references for index %d,"
- "no need to modify vlan table\n", index);
- goto out;
- }
- table->entries[index] = 0;
- mlx4_SET_PORT_vlan_table(dev, port, table->entries);
- --table->total;
-out:
- up(&table->vlan_sem);
-}
-EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);
-
-int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port,
- int reset_qkey_viols, u32 cap_mask)
-{
- struct mlx4_cmd_mailbox *mailbox;
- int err;
- u8 is_eth = (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) ? 1 : 0;
-
- mailbox = mlx4_alloc_cmd_mailbox(dev);
- if (IS_ERR(mailbox))
- return PTR_ERR(mailbox);
-
- memset(mailbox->buf, 0, 256);
- if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
+/*\r
+ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.\r
+ *\r
+ * This software is available to you under a choice of one of two\r
+ * licenses. You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ */\r
+\r
+#include "mlx4.h"\r
+#include "cmd.h"\r
+\r
+\r
+void mlx4_init_mac_table(struct mlx4_dev *dev, u8 port)\r
+{\r
+ struct mlx4_mac_table *table = &mlx4_priv(dev)->port[port].mac_table;\r
+ int i;\r
+\r
+ sema_init(&table->mac_sem, 1);\r
+ for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {\r
+ table->entries[i] = 0;\r
+ table->refs[i] = 0;\r
+ }\r
+ table->max = 1 << dev->caps.log_num_macs;\r
+ table->total = 0;\r
+}\r
+\r
+void mlx4_init_vlan_table(struct mlx4_dev *dev, u8 port)\r
+{\r
+ struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;\r
+ int i;\r
+\r
+ sema_init(&table->vlan_sem, 1);\r
+ for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {\r
+ table->entries[i] = 0;\r
+ table->refs[i] = 0;\r
+ }\r
+ table->max = 1 << dev->caps.log_num_vlans;\r
+ table->total = 0;\r
+}\r
+\r
+static int mlx4_SET_PORT_mac_table(struct mlx4_dev *dev, u8 port,\r
+ __be64 *entries)\r
+{\r
+ struct mlx4_cmd_mailbox *mailbox;\r
+ u32 in_mod;\r
+ int err;\r
+\r
+ mailbox = mlx4_alloc_cmd_mailbox(dev);\r
+ if (IS_ERR(mailbox))\r
+ return PTR_ERR(mailbox);\r
+\r
+ memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);\r
+\r
+ in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;\r
+ err = mlx4_cmd(dev, mailbox->dma.da, in_mod, 1, MLX4_CMD_SET_PORT,\r
+ MLX4_CMD_TIME_CLASS_B);\r
+\r
+ mlx4_free_cmd_mailbox(dev, mailbox);\r
+ return err;\r
+}\r
+\r
+int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index)\r
+{\r
+ struct mlx4_mac_table *table =\r
+ &mlx4_priv(dev)->port[port - 1].mac_table;\r
+ int i, err = 0;\r
+ int free = -1;\r
+ u64 valid = 1;\r
+\r
+ if ( mlx4_is_barred(dev) )\r
+ return -EFAULT;\r
+\r
+ mlx4_dbg(dev, "Registering mac : 0x%llx\n", mac);\r
+ down(&table->mac_sem);\r
+ for (i = 0; i < MLX4_MAX_MAC_NUM - 1; i++) {\r
+ if (free < 0 && !table->refs[i]) {\r
+ free = i;\r
+ continue;\r
+ }\r
+\r
+ if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {\r
+ /* Mac already registered, increase refernce count */\r
+ *index = i;\r
+ ++table->refs[i];\r
+ goto out;\r
+ }\r
+ }\r
+ mlx4_dbg(dev, "Free mac index is %d\n", free);\r
+\r
+ if (table->total == table->max) {\r
+ /* No free mac entries */\r
+ err = -ENOSPC;\r
+ goto out;\r
+ }\r
+\r
+ /* Register new MAC */\r
+ table->refs[free] = 1;\r
+ table->entries[free] = cpu_to_be64(mac | valid << MLX4_MAC_VALID_SHIFT);\r
+\r
+ err = mlx4_SET_PORT_mac_table(dev, port, table->entries);\r
+ if (unlikely(err)) {\r
+ mlx4_err(dev, "Failed adding mac: 0x%llx\n", mac);\r
+ table->refs[free] = 0;\r
+ table->entries[free] = 0;\r
+ goto out;\r
+ }\r
+\r
+ *index = free;\r
+ ++table->total;\r
+out:\r
+ up(&table->mac_sem);\r
+ return err;\r
+}\r
+EXPORT_SYMBOL_GPL(mlx4_register_mac);\r
+\r
+void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index)\r
+{\r
+ struct mlx4_mac_table *table =\r
+ &mlx4_priv(dev)->port[port - 1].mac_table;\r
+\r
+ down(&table->mac_sem);\r
+ if (!table->refs[index]) {\r
+ mlx4_warn(dev, "No mac entry for index %d\n", index);\r
+ goto out;\r
+ }\r
+ if (--table->refs[index]) {\r
+ mlx4_warn(dev, "Have more references for index %d,"\r
+ "no need to modify mac table\n", index);\r
+ goto out;\r
+ }\r
+ table->entries[index] = 0;\r
+ if ( !mlx4_is_barred(dev) )\r
+ mlx4_SET_PORT_mac_table(dev, port, table->entries);\r
+ --table->total;\r
+out:\r
+ up(&table->mac_sem);\r
+}\r
+EXPORT_SYMBOL_GPL(mlx4_unregister_mac);\r
+\r
+static int mlx4_SET_PORT_vlan_table(struct mlx4_dev *dev, u8 port,\r
+ __be32 *entries)\r
+{\r
+ struct mlx4_cmd_mailbox *mailbox;\r
+ u32 in_mod;\r
+ int err;\r
+\r
+ mailbox = mlx4_alloc_cmd_mailbox(dev);\r
+ if (IS_ERR(mailbox))\r
+ return PTR_ERR(mailbox);\r
+\r
+ memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);\r
+ in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;\r
+ err = mlx4_cmd(dev, mailbox->dma.da, in_mod, 1, MLX4_CMD_SET_PORT,\r
+ MLX4_CMD_TIME_CLASS_B);\r
+\r
+ mlx4_free_cmd_mailbox(dev, mailbox);\r
+\r
+ return err;\r
+}\r
+\r
+int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)\r
+{\r
+ struct mlx4_vlan_table *table =\r
+ &mlx4_priv(dev)->port[port - 1].vlan_table;\r
+ int i, err = 0;\r
+ int free = -1;\r
+\r
+ down(&table->vlan_sem);\r
+ for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {\r
+ if (free < 0 && (table->refs[i] == 0)) {\r
+ free = i;\r
+ continue;\r
+ }\r
+\r
+ if (table->refs[i] &&\r
+ (vlan == (MLX4_VLAN_MASK &\r
+ be32_to_cpu(table->entries[i])))) {\r
+ /* Vlan already registered, increase refernce count */\r
+ *index = i;\r
+ ++table->refs[i];\r
+ goto out;\r
+ }\r
+ }\r
+\r
+ if (table->total == table->max) {\r
+ /* No free vlan entries */\r
+ err = -ENOSPC;\r
+ goto out;\r
+ }\r
+\r
+ /* Register new MAC */\r
+ table->refs[free] = 1;\r
+ table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);\r
+\r
+ err = mlx4_SET_PORT_vlan_table(dev, port, table->entries);\r
+ if (unlikely(err)) {\r
+ mlx4_warn(dev, "Failed adding vlan: %u\n", vlan);\r
+ table->refs[free] = 0;\r
+ table->entries[free] = 0;\r
+ goto out;\r
+ }\r
+\r
+ *index = free;\r
+ ++table->total;\r
+out:\r
+ up(&table->vlan_sem);\r
+ return err;\r
+}\r
+EXPORT_SYMBOL_GPL(mlx4_register_vlan);\r
+\r
+void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)\r
+{\r
+ struct mlx4_vlan_table *table =\r
+ &mlx4_priv(dev)->port[port - 1].vlan_table;\r
+\r
+ down(&table->vlan_sem);\r
+ if (!table->refs[index]) {\r
+ mlx4_warn(dev, "No vlan entry for index %d\n", index);\r
+ goto out;\r
+ }\r
+ if (--table->refs[index]) {\r
+ mlx4_dbg(dev, "Have more references for index %d,"\r
+ "no need to modify vlan table\n", index);\r
+ goto out;\r
+ }\r
+ table->entries[index] = 0;\r
+ mlx4_SET_PORT_vlan_table(dev, port, table->entries);\r
+ --table->total;\r
+out:\r
+ up(&table->vlan_sem);\r
+}\r
+EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);\r
+\r
+int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, \r
+ int reset_qkey_viols, u32 cap_mask)\r
+{\r
+ struct mlx4_cmd_mailbox *mailbox;\r
+ int err;\r
+ u8 is_eth = (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) ? 1 : 0;\r
+\r
+ mailbox = mlx4_alloc_cmd_mailbox(dev);\r
+ if (IS_ERR(mailbox))\r
+ return PTR_ERR(mailbox);\r
+\r
+ memset(mailbox->buf, 0, 256);\r
+ if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {\r
*(u8 *) mailbox->buf = (u8)(!!reset_qkey_viols << 6);
((__be32 *) mailbox->buf)[2] = cpu_to_be32(cap_mask);
} else {
((u8 *) mailbox->buf)[3] = (u8)!!reset_qkey_viols;
((__be32 *) mailbox->buf)[1] = cpu_to_be32(cap_mask);
}
-
- if (is_eth) {
- ((u8 *) mailbox->buf)[3] = 7;
- ((__be16 *) mailbox->buf)[3] =
- cpu_to_be16(dev->caps.eth_mtu_cap[port] +
- ETH_HLEN + ETH_FCS_LEN);
- ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15);
- ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15);
- }
- err = mlx4_cmd(dev, mailbox->dma.da, port, is_eth, MLX4_CMD_SET_PORT,
- MLX4_CMD_TIME_CLASS_B);
-
- mlx4_free_cmd_mailbox(dev, mailbox);
- return err;
-}
-
+ \r
+ if (is_eth) {\r
+ ((u8 *) mailbox->buf)[3] = 7;\r
+ ((__be16 *) mailbox->buf)[3] =\r
+ cpu_to_be16(dev->caps.eth_mtu_cap[port] +\r
+ ETH_HLEN + ETH_FCS_LEN);\r
+ ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15);\r
+ ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15);\r
+ }\r
+ err = mlx4_cmd(dev, mailbox->dma.da, port, is_eth, MLX4_CMD_SET_PORT,\r
+ MLX4_CMD_TIME_CLASS_B);\r
+\r
+ mlx4_free_cmd_mailbox(dev, mailbox);\r
+ return err;\r
+}\r
+\r
static u16 op[MLX4_QP_NUM_STATE][MLX4_QP_NUM_STATE];
static int op_inited = 0;
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
if (!op_inited) {
op[MLX4_QP_STATE_RST][MLX4_QP_STATE_RST] = MLX4_CMD_2RST_QP;
op[MLX4_QP_STATE_RST][MLX4_QP_STATE_ERR] = MLX4_CMD_2ERR_QP;
struct mlx4_qp_table *qp_table = &priv->qp_table;
int err;
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
if (!qpn)
return -EINVAL;
if (atomic_dec_and_test(&qp->refcount))
complete(&qp->free);
- wait_for_completion(&qp->free);
+ if (!mlx4_is_barred(dev))
+ wait_for_completion(&qp->free);
mlx4_table_put(dev, &qp_table->cmpt_table, qp->qpn);
mlx4_table_put(dev, &qp_table->rdmarc_table, qp->qpn);
int err;
UNREFERENCED_PARAMETER(xrcd);
+ if ( mlx4_is_barred(dev) )
+ return -EFAULT;
+
srq->srqn = mlx4_bitmap_alloc(&srq_table->bitmap);
if (srq->srqn == -1)
return -ENOMEM;
{
int err;
+ if ( mlx4_is_barred(dev) )
+ return;
+
err = mlx4_HW2SW_SRQ(dev, NULL, srq->srqn);
if (err)
mlx4_warn(dev, "HW2SW_SRQ failed (%d) for SRQN %06x\n", err, srq->srqn);
if (atomic_dec_and_test(&srq->refcount))
complete(&srq->free);
- wait_for_completion(&srq->free);
+ if (!mlx4_is_barred(dev))
+ wait_for_completion(&srq->free);
mlx4_table_put(dev, &srq_table->table, srq->srqn);
mlx4_bitmap_free(&srq_table->bitmap, srq->srqn);
&p_ib_ah_attr->grh.traffic_class, &p_ib_ah_attr->grh.flow_label );\r
err = p_ib_dev->x.find_cached_gid((struct ib_device *)p_ib_dev, \r
(union ib_gid *)p_ib_av_attr->grh.src_gid.raw, &port_num, &gid_index);\r
- if (err) {\r
-\r
+ if (err) {\r\r
HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,\r
("ib_find_cached_gid failed %d (%#x). Using default: sgid_index = 0\n", err, err));\r
gid_index = 0;\r
err = p_ib_dev->x.get_cached_gid((struct ib_device *)p_ib_dev, \r
p_ib_ah_attr->port_num, p_ib_ah_attr->grh.sgid_index,\r
(union ib_gid*)p_ib_av_attr->grh.src_gid.raw );\r
- if (err) {\r
-\r
+ if (err) {\r\r
HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,\r
("ib_get_cached_gid failed %d (%#x). Using default: sgid_index = 0\n", err, err));\r
}\r
return dev->flags & MLX4_FLAG_LIVEFISH;
}
+static inline int mlx4_is_barred(struct mlx4_dev *dev)
+{
+ return dev->flags & (MLX4_FLAG_RESET_CLIENT | MLX4_FLAG_RESET_DRIVER);
+}
+
+static inline int mlx4_is_in_reset(struct mlx4_dev *dev)
+{
+ return dev->flags & MLX4_FLAG_RESET_STARTED;
+}
+
#endif
\r
#define MTNIC_MAX_PORTS 2\r
\r
-#define MAX_PORT_SIZE 250000\r
#define MXE_INTERFACE_VERSION 2\r
\r
enum mtnic_state {\r
CARD_DISABLED\r
};\r
\r
+struct _MP_PORT;\r
+\r
typedef struct {\r
enum mtnic_state state;\r
- NDIS_WORK_ITEM PortStateWorkItem;\r
- NDIS_WORK_ITEM ResetWorkItem;\r
KEVENT ConfigChangeEvent; \r
- KTIMER HeardBeatTimer; \r
- LONG ResetCount;\r
\r
// Objects that are needed in order to work with the hw\r
\r
{\r
PVOID Context;\r
LONG NoOfConnectedPorts;\r
- ULONG ulAllocatePortObjSize;\r
+\r
NicData_t NicData;\r
-#ifdef _WIN64 \r
- UCHAR pad[0x8];\r
-#else\r
- UCHAR pad[0x8]; \r
-#endif \r
-#ifdef MTNIC\r
- C_ASSERT(MAX_PORT_SIZE >= sizeof(struct _MP_PORT));\r
- MP_PORT ports[MTNIC_MAX_PORTS];\r
-#else\r
- UCHAR ports[MAX_PORT_SIZE * MTNIC_MAX_PORTS];\r
-#endif \r
-};\r
\r
-C_ASSERT((FIELD_OFFSET(struct VipBusIfc, ports) % 16) == 0);\r
+ struct _MP_PORT *ports[MTNIC_MAX_PORTS];\r
+ \r
+};\r
\r
\r
\r