]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
RDMA/ocrdma: set vlan present bit for user AH
authorDevesh Sharma <devesh.sharma@emulex.com>
Thu, 18 Dec 2014 08:43:07 +0000 (14:13 +0530)
committerRoland Dreier <roland@purestorage.com>
Wed, 18 Feb 2015 16:31:05 +0000 (08:31 -0800)
For the AH that describs a VLAN interface details, vlan present bit
needs to be set during posting a WQE. This patch adds the code to
allow it happening.

Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com>
Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/ocrdma/ocrdma_ah.c
drivers/infiniband/hw/ocrdma/ocrdma_ah.h
drivers/infiniband/hw/ocrdma/ocrdma_sli.h
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c

index b80b57b40043bb3c458e21402c7aa73a973926ee..d812904f398473d1502bb979d6d822c04b55f2b8 100644 (file)
 #define OCRDMA_VID_PCP_SHIFT   0xD
 
 static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
-                       struct ib_ah_attr *attr, union ib_gid *sgid, int pdid)
+                       struct ib_ah_attr *attr, union ib_gid *sgid,
+                       int pdid, bool *isvlan)
 {
        int status = 0;
-       u16 vlan_tag; bool vlan_enabled = false;
+       u16 vlan_tag;
        struct ocrdma_eth_vlan eth;
        struct ocrdma_grh grh;
        int eth_sz;
@@ -61,7 +62,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
                vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT;
                eth.vlan_tag = cpu_to_be16(vlan_tag);
                eth_sz = sizeof(struct ocrdma_eth_vlan);
-               vlan_enabled = true;
+               *isvlan = true;
        } else {
                eth.eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE);
                eth_sz = sizeof(struct ocrdma_eth_basic);
@@ -84,7 +85,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
        /* Eth HDR */
        memcpy(&ah->av->eth_hdr, &eth, eth_sz);
        memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh));
-       if (vlan_enabled)
+       if (*isvlan)
                ah->av->valid |= OCRDMA_AV_VLAN_VALID;
        ah->av->valid = cpu_to_le32(ah->av->valid);
        return status;
@@ -93,6 +94,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
 struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
 {
        u32 *ahid_addr;
+       bool isvlan = false;
        int status;
        struct ocrdma_ah *ah;
        struct ocrdma_pd *pd = get_ocrdma_pd(ibpd);
@@ -129,15 +131,20 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
                }
        }
 
-       status = set_av_attr(dev, ah, attr, &sgid, pd->id);
+       status = set_av_attr(dev, ah, attr, &sgid, pd->id, &isvlan);
        if (status)
                goto av_conf_err;
 
        /* if pd is for the user process, pass the ah_id to user space */
        if ((pd->uctx) && (pd->uctx->ah_tbl.va)) {
                ahid_addr = pd->uctx->ah_tbl.va + attr->dlid;
-               *ahid_addr = ah->id;
+               *ahid_addr = 0;
+               *ahid_addr |= ah->id & OCRDMA_AH_ID_MASK;
+               if (isvlan)
+                       *ahid_addr |= (OCRDMA_AH_VLAN_VALID_MASK <<
+                                      OCRDMA_AH_VLAN_VALID_SHIFT);
        }
+
        return &ah->ibah;
 
 av_conf_err:
index 8ac49e7f96d1585c7fb94049dd7db88a0699b7f4..726a87cf22dcb215d2a105f08a054395bb0c6804 100644 (file)
 #ifndef __OCRDMA_AH_H__
 #define __OCRDMA_AH_H__
 
+enum {
+       OCRDMA_AH_ID_MASK               = 0x3FF,
+       OCRDMA_AH_VLAN_VALID_MASK       = 0x01,
+       OCRDMA_AH_VLAN_VALID_SHIFT      = 0x1F
+};
+
 struct ib_ah *ocrdma_create_ah(struct ib_pd *, struct ib_ah_attr *);
 int ocrdma_destroy_ah(struct ib_ah *);
 int ocrdma_query_ah(struct ib_ah *, struct ib_ah_attr *);
index 801883aa41453a088f4013af4cc6d92e2bbeebfd..243c87c8bd65d09026f46ee12e3ee3b9109ce155 100644 (file)
@@ -1734,6 +1734,7 @@ enum {
        OCRDMA_FLAG_FENCE_R     = 0x8,
        OCRDMA_FLAG_SOLICIT     = 0x10,
        OCRDMA_FLAG_IMM         = 0x20,
+       OCRDMA_FLAG_AH_VLAN_PR  = 0x40,
 
        /* Stag flags */
        OCRDMA_LKEY_FLAG_LOCAL_WR       = 0x1,
index 4d5f581af49a70543043abcc86f94423da0c87fa..5f656b936de4fc497aa76e555940793b06422bfc 100644 (file)
@@ -1937,6 +1937,8 @@ static void ocrdma_build_ud_hdr(struct ocrdma_qp *qp,
        else
                ud_hdr->qkey = wr->wr.ud.remote_qkey;
        ud_hdr->rsvd_ahid = ah->id;
+       if (ah->av->valid & OCRDMA_AV_VLAN_VALID)
+               hdr->cw |= (OCRDMA_FLAG_AH_VLAN_PR << OCRDMA_WQE_FLAGS_SHIFT);
 }
 
 static void ocrdma_build_sges(struct ocrdma_hdr_wqe *hdr,