]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'rdma-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Jun 2012 18:00:07 +0000 (11:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Jun 2012 18:00:07 +0000 (11:00 -0700)
Pull InfiniBand/RDMA fixes from Roland Dreier:
 - Fixes to new ocrdma driver
 - Typo in test in CMA

* tag 'rdma-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
  RDMA/cma: QP type check on received REQs should be AND not OR
  RDMA/ocrdma: Fix off by one in ocrdma_query_gid()
  RDMA/ocrdma: Fixed RQ error CQE polling
  RDMA/ocrdma: Correct queue SGE calculation
  RDMA/ocrdma: Correct reported max queue sizes
  RDMA/ocrdma: Fixed GID table for vlan and events

drivers/infiniband/core/cma.c
drivers/infiniband/hw/ocrdma/ocrdma.h
drivers/infiniband/hw/ocrdma/ocrdma_hw.c
drivers/infiniband/hw/ocrdma/ocrdma_main.c
drivers/infiniband/hw/ocrdma/ocrdma_sli.h
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c

index 55d5642eb10ada70ec2f87419e5909ae52906323..2e826f9702c6d76cfc895c24466c068a8e042a83 100644 (file)
@@ -1184,7 +1184,7 @@ static void cma_set_req_event_data(struct rdma_cm_event *event,
 
 static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event)
 {
-       return (((ib_event->event == IB_CM_REQ_RECEIVED) ||
+       return (((ib_event->event == IB_CM_REQ_RECEIVED) &&
                 (ib_event->param.req_rcvd.qp_type == id->qp_type)) ||
                ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) &&
                 (id->qp_type == IB_QPT_UD)) ||
index 037f5cea85bd82293961a87180b57ea8ae56a447..48970af236794cea69ace19502a874071c1ee0cb 100644 (file)
@@ -61,6 +61,7 @@ struct ocrdma_dev_attr {
        u32 max_inline_data;
        int max_send_sge;
        int max_recv_sge;
+       int max_srq_sge;
        int max_mr;
        u64 max_mr_size;
        u32 max_num_mr_pbl;
index 9343a15229774652c34276e160795487b5075e43..71942af4fce94695753dacbb8417ee191aaaf9a6 100644 (file)
@@ -990,8 +990,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
                              struct ocrdma_dev_attr *attr,
                              struct ocrdma_mbx_query_config *rsp)
 {
-       int max_q_mem;
-
        attr->max_pd =
            (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >>
            OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT;
@@ -1004,6 +1002,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
        attr->max_recv_sge = (rsp->max_write_send_sge &
                              OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >>
            OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT;
+       attr->max_srq_sge = (rsp->max_srq_rqe_sge &
+                             OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >>
+           OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET;
        attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp &
                                OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >>
            OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT;
@@ -1037,18 +1038,15 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
        attr->max_inline_data =
            attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) +
                              sizeof(struct ocrdma_sge));
-       max_q_mem = OCRDMA_Q_PAGE_BASE_SIZE << (OCRDMA_MAX_Q_PAGE_SIZE_CNT - 1);
-       /* hw can queue one less then the configured size,
-        * so publish less by one to stack.
-        */
        if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
-               dev->attr.max_wqe = max_q_mem / dev->attr.wqe_size;
                attr->ird = 1;
                attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE;
                attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES;
-       } else
-               dev->attr.max_wqe = (max_q_mem / dev->attr.wqe_size) - 1;
-       dev->attr.max_rqe = (max_q_mem / dev->attr.rqe_size) - 1;
+       }
+       dev->attr.max_wqe = rsp->max_wqes_rqes_per_q >>
+                OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET;
+       dev->attr.max_rqe = rsp->max_wqes_rqes_per_q &
+               OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK;
 }
 
 static int ocrdma_check_fw_config(struct ocrdma_dev *dev,
index 04fef3de6d75f618a990d7e76730311a24827b68..b050e629e9c3bd19d2e089fdd7792a53d49fe2b0 100644 (file)
@@ -97,13 +97,11 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr,
        sgid->raw[15] = mac_addr[5];
 }
 
-static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
+static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
                            bool is_vlan, u16 vlan_id)
 {
        int i;
-       bool found = false;
        union ib_gid new_sgid;
-       int free_idx = OCRDMA_MAX_SGID;
        unsigned long flags;
 
        memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid));
@@ -115,23 +113,19 @@ static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
                if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid,
                            sizeof(union ib_gid))) {
                        /* found free entry */
-                       if (!found) {
-                               free_idx = i;
-                               found = true;
-                               break;
-                       }
+                       memcpy(&dev->sgid_tbl[i], &new_sgid,
+                              sizeof(union ib_gid));
+                       spin_unlock_irqrestore(&dev->sgid_lock, flags);
+                       return true;
                } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid,
                                   sizeof(union ib_gid))) {
                        /* entry already present, no addition is required. */
                        spin_unlock_irqrestore(&dev->sgid_lock, flags);
-                       return;
+                       return false;
                }
        }
-       /* if entry doesn't exist and if table has some space, add entry */
-       if (found)
-               memcpy(&dev->sgid_tbl[free_idx], &new_sgid,
-                      sizeof(union ib_gid));
        spin_unlock_irqrestore(&dev->sgid_lock, flags);
+       return false;
 }
 
 static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
@@ -167,7 +161,8 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev)
        ocrdma_get_guid(dev, &sgid->raw[8]);
 }
 
-static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
 {
        struct net_device *netdev, *tmp;
        u16 vlan_id;
@@ -175,8 +170,6 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
 
        netdev = dev->nic_info.netdev;
 
-       ocrdma_add_default_sgid(dev);
-
        rcu_read_lock();
        for_each_netdev_rcu(&init_net, tmp) {
                if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) {
@@ -194,10 +187,23 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
                }
        }
        rcu_read_unlock();
+}
+#else
+static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
+{
+
+}
+#endif /* VLAN */
+
+static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
+{
+       ocrdma_add_default_sgid(dev);
+       ocrdma_add_vlan_sgids(dev);
        return 0;
 }
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \
+defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 
 static int ocrdma_inet6addr_event(struct notifier_block *notifier,
                                  unsigned long event, void *ptr)
@@ -208,6 +214,7 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
        struct ib_event gid_event;
        struct ocrdma_dev *dev;
        bool found = false;
+       bool updated = false;
        bool is_vlan = false;
        u16 vid = 0;
 
@@ -233,23 +240,21 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
        mutex_lock(&dev->dev_lock);
        switch (event) {
        case NETDEV_UP:
-               ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid);
+               updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid);
                break;
        case NETDEV_DOWN:
-               found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid);
-               if (found) {
-                       /* found the matching entry, notify
-                        * the consumers about it
-                        */
-                       gid_event.device = &dev->ibdev;
-                       gid_event.element.port_num = 1;
-                       gid_event.event = IB_EVENT_GID_CHANGE;
-                       ib_dispatch_event(&gid_event);
-               }
+               updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid);
                break;
        default:
                break;
        }
+       if (updated) {
+               /* GID table updated, notify the consumers about it */
+               gid_event.device = &dev->ibdev;
+               gid_event.element.port_num = 1;
+               gid_event.event = IB_EVENT_GID_CHANGE;
+               ib_dispatch_event(&gid_event);
+       }
        mutex_unlock(&dev->dev_lock);
        return NOTIFY_OK;
 }
@@ -258,7 +263,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = {
        .notifier_call = ocrdma_inet6addr_event
 };
 
-#endif /* IPV6 */
+#endif /* IPV6 and VLAN */
 
 static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device,
                                              u8 port_num)
index 7fd80cc0f0374159d5b9de9492bc6bfc64a838e4..c75cbdfa87e7b82a3e3d6cd5d1e7be78b4dd1f19 100644 (file)
@@ -418,6 +418,9 @@ enum {
 
        OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT         = 0,
        OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK          = 0xFFFF,
+       OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT        = 16,
+       OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK         = 0xFFFF <<
+                               OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT,
 
        OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT       = 0,
        OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK        = 0xFFFF,
@@ -458,7 +461,7 @@ enum {
                                OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET,
        OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET     = 0,
        OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK       = 0xFFFF <<
-                               OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET,
+                               OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET,
 
        OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET              = 16,
        OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK                = 0xFFFF <<
index d16d172b6b6bd416b9114df432fd132768114236..2e2e7aecc9907a87432dce09b218e046a141c124 100644 (file)
@@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port,
 
        dev = get_ocrdma_dev(ibdev);
        memset(sgid, 0, sizeof(*sgid));
-       if (index > OCRDMA_MAX_SGID)
+       if (index >= OCRDMA_MAX_SGID)
                return -EINVAL;
 
        memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid));
@@ -83,8 +83,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
                                        IB_DEVICE_SHUTDOWN_PORT |
                                        IB_DEVICE_SYS_IMAGE_GUID |
                                        IB_DEVICE_LOCAL_DMA_LKEY;
-       attr->max_sge = dev->attr.max_send_sge;
-       attr->max_sge_rd = dev->attr.max_send_sge;
+       attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_srq_sge);
+       attr->max_sge_rd = 0;
        attr->max_cq = dev->attr.max_cq;
        attr->max_cqe = dev->attr.max_cqe;
        attr->max_mr = dev->attr.max_mr;
@@ -97,7 +97,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
            min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp);
        attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp;
        attr->max_srq = (dev->attr.max_qp - 1);
-       attr->max_srq_sge = attr->max_sge;
+       attr->max_srq_sge = attr->max_srq_sge;
        attr->max_srq_wr = dev->attr.max_rqe;
        attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay;
        attr->max_fast_reg_page_list_len = 0;
@@ -2301,8 +2301,10 @@ static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe,
                        *stop = true;
                        expand = false;
                }
-       } else
+       } else {
+               *polled = true;
                expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status);
+       }
        return expand;
 }