aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2012-08-03 04:40:40 -0400
committerRoland Dreier <roland@purestorage.com>2012-09-30 23:33:30 -0400
commit1ffeb2eb8be9936e9dc1f9af2d5f4c14d69a0d36 (patch)
tree1e79a4a6c3955a21c7802618d58b3bd7605a937e
parent73aaa7418f8069103ca56fc620b3cd16c5a37d6e (diff)
IB/mlx4: SR-IOV IB context objects and proxy/tunnel SQP support
1. Introduce the basic SR-IOV parvirtualization context objects for multiplexing and demultiplexing MADs. 2. Introduce support for the new proxy and tunnel QP types. This patch introduces the objects required by the master for managing QP paravirtualization for guests. struct mlx4_ib_sriov is created by the master only. It is a container for the following: 1. All the info required by the PPF to multiplex and de-multiplex MADs (including those from the PF). (struct mlx4_ib_demux_ctx demux) 2. All the info required to manage alias GUIDs (i.e., the GUID at index 0 that each guest perceives. In fact, this is not the GUID which is actually at index 0, but is, in fact, the GUID which is at index[<VF number>] in the physical table. 3. structures which are used to manage CM paravirtualization 4. structures for managing the real special QPs when running in SR-IOV mode. The real SQPs are controlled by the PPF in this case. All SQPs created and controlled by the ib core layer are proxy SQP. struct mlx4_ib_demux_ctx contains the information per port needed to manage paravirtualization: 1. All multicast paravirt info 2. All tunnel-qp paravirt info for the port. 3. GUID-table and GUID-prefix for the port 4. work queues. struct mlx4_ib_demux_pv_ctx contains all the info for managing the paravirtualized QPs for one slave/port. struct mlx4_ib_demux_pv_qp contains the info need to run an individual QP (either tunnel qp or real SQP). Note: We made use of the 2 most significant bits in enum mlx4_ib_qp_flags (based on enum ib_qp_create_flags in ib_verbs.h). We need these bits in the low-level driver for internal purposes. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c31
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h128
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c616
-rw-r--r--include/linux/mlx4/device.h1
-rw-r--r--include/linux/mlx4/qp.h3
5 files changed, 702 insertions, 77 deletions
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 6d4ef71cbcd..c9eb6a6815c 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -547,6 +547,26 @@ static int mlx4_ib_ipoib_csum_ok(__be16 status, __be16 checksum)
547 checksum == cpu_to_be16(0xffff); 547 checksum == cpu_to_be16(0xffff);
548} 548}
549 549
550static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct ib_wc *wc,
551 unsigned tail, struct mlx4_cqe *cqe)
552{
553 struct mlx4_ib_proxy_sqp_hdr *hdr;
554
555 ib_dma_sync_single_for_cpu(qp->ibqp.device,
556 qp->sqp_proxy_rcv[tail].map,
557 sizeof (struct mlx4_ib_proxy_sqp_hdr),
558 DMA_FROM_DEVICE);
559 hdr = (struct mlx4_ib_proxy_sqp_hdr *) (qp->sqp_proxy_rcv[tail].addr);
560 wc->pkey_index = be16_to_cpu(hdr->tun.pkey_index);
561 wc->slid = be16_to_cpu(hdr->tun.slid_mac_47_32);
562 wc->sl = (u8) (be16_to_cpu(hdr->tun.sl_vid) >> 12);
563 wc->src_qp = be32_to_cpu(hdr->tun.flags_src_qp) & 0xFFFFFF;
564 wc->wc_flags |= (hdr->tun.g_ml_path & 0x80) ? (IB_WC_GRH) : 0;
565 wc->dlid_path_bits = 0;
566
567 return 0;
568}
569
550static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, 570static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
551 struct mlx4_ib_qp **cur_qp, 571 struct mlx4_ib_qp **cur_qp,
552 struct ib_wc *wc) 572 struct ib_wc *wc)
@@ -559,6 +579,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
559 int is_error; 579 int is_error;
560 u32 g_mlpath_rqpn; 580 u32 g_mlpath_rqpn;
561 u16 wqe_ctr; 581 u16 wqe_ctr;
582 unsigned tail = 0;
562 583
563repoll: 584repoll:
564 cqe = next_cqe_sw(cq); 585 cqe = next_cqe_sw(cq);
@@ -634,7 +655,8 @@ repoll:
634 mlx4_ib_free_srq_wqe(srq, wqe_ctr); 655 mlx4_ib_free_srq_wqe(srq, wqe_ctr);
635 } else { 656 } else {
636 wq = &(*cur_qp)->rq; 657 wq = &(*cur_qp)->rq;
637 wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)]; 658 tail = wq->tail & (wq->wqe_cnt - 1);
659 wc->wr_id = wq->wrid[tail];
638 ++wq->tail; 660 ++wq->tail;
639 } 661 }
640 662
@@ -717,6 +739,13 @@ repoll:
717 break; 739 break;
718 } 740 }
719 741
742 if (mlx4_is_mfunc(to_mdev(cq->ibcq.device)->dev)) {
743 if ((*cur_qp)->mlx4_ib_qp_type &
744 (MLX4_IB_QPT_PROXY_SMI_OWNER |
745 MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI))
746 return use_tunnel_data(*cur_qp, cq, wc, tail, cqe);
747 }
748
720 wc->slid = be16_to_cpu(cqe->rlid); 749 wc->slid = be16_to_cpu(cqe->rlid);
721 g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn); 750 g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn);
722 wc->src_qp = g_mlpath_rqpn & 0xffffff; 751 wc->src_qp = g_mlpath_rqpn & 0xffffff;
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index c136bb618e2..1248d576b03 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -133,8 +133,10 @@ struct mlx4_ib_wq {
133}; 133};
134 134
135enum mlx4_ib_qp_flags { 135enum mlx4_ib_qp_flags {
136 MLX4_IB_QP_LSO = 1 << 0, 136 MLX4_IB_QP_LSO = IB_QP_CREATE_IPOIB_UD_LSO,
137 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = 1 << 1, 137 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK,
138 MLX4_IB_SRIOV_TUNNEL_QP = 1 << 30,
139 MLX4_IB_SRIOV_SQP = 1 << 31,
138}; 140};
139 141
140struct mlx4_ib_gid_entry { 142struct mlx4_ib_gid_entry {
@@ -144,6 +146,68 @@ struct mlx4_ib_gid_entry {
144 u8 port; 146 u8 port;
145}; 147};
146 148
149enum mlx4_ib_qp_type {
150 /*
151 * IB_QPT_SMI and IB_QPT_GSI have to be the first two entries
152 * here (and in that order) since the MAD layer uses them as
153 * indices into a 2-entry table.
154 */
155 MLX4_IB_QPT_SMI = IB_QPT_SMI,
156 MLX4_IB_QPT_GSI = IB_QPT_GSI,
157
158 MLX4_IB_QPT_RC = IB_QPT_RC,
159 MLX4_IB_QPT_UC = IB_QPT_UC,
160 MLX4_IB_QPT_UD = IB_QPT_UD,
161 MLX4_IB_QPT_RAW_IPV6 = IB_QPT_RAW_IPV6,
162 MLX4_IB_QPT_RAW_ETHERTYPE = IB_QPT_RAW_ETHERTYPE,
163 MLX4_IB_QPT_RAW_PACKET = IB_QPT_RAW_PACKET,
164 MLX4_IB_QPT_XRC_INI = IB_QPT_XRC_INI,
165 MLX4_IB_QPT_XRC_TGT = IB_QPT_XRC_TGT,
166
167 MLX4_IB_QPT_PROXY_SMI_OWNER = 1 << 16,
168 MLX4_IB_QPT_PROXY_SMI = 1 << 17,
169 MLX4_IB_QPT_PROXY_GSI = 1 << 18,
170 MLX4_IB_QPT_TUN_SMI_OWNER = 1 << 19,
171 MLX4_IB_QPT_TUN_SMI = 1 << 20,
172 MLX4_IB_QPT_TUN_GSI = 1 << 21,
173};
174
175#define MLX4_IB_QPT_ANY_SRIOV (MLX4_IB_QPT_PROXY_SMI_OWNER | \
176 MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI | MLX4_IB_QPT_TUN_SMI_OWNER | \
177 MLX4_IB_QPT_TUN_SMI | MLX4_IB_QPT_TUN_GSI)
178
179struct mlx4_ib_tunnel_header {
180 struct mlx4_av av;
181 __be32 remote_qpn;
182 __be32 qkey;
183 __be16 vlan;
184 u8 mac[6];
185 __be16 pkey_index;
186 u8 reserved[6];
187};
188
189struct mlx4_ib_buf {
190 void *addr;
191 dma_addr_t map;
192};
193
194struct mlx4_rcv_tunnel_hdr {
195 __be32 flags_src_qp; /* flags[6:5] is defined for VLANs:
196 * 0x0 - no vlan was in the packet
197 * 0x01 - C-VLAN was in the packet */
198 u8 g_ml_path; /* gid bit stands for ipv6/4 header in RoCE */
199 u8 reserved;
200 __be16 pkey_index;
201 __be16 sl_vid;
202 __be16 slid_mac_47_32;
203 __be32 mac_31_0;
204};
205
206struct mlx4_ib_proxy_sqp_hdr {
207 struct ib_grh grh;
208 struct mlx4_rcv_tunnel_hdr tun;
209} __packed;
210
147struct mlx4_ib_qp { 211struct mlx4_ib_qp {
148 struct ib_qp ibqp; 212 struct ib_qp ibqp;
149 struct mlx4_qp mqp; 213 struct mlx4_qp mqp;
@@ -159,6 +223,7 @@ struct mlx4_ib_qp {
159 int sq_spare_wqes; 223 int sq_spare_wqes;
160 struct mlx4_ib_wq sq; 224 struct mlx4_ib_wq sq;
161 225
226 enum mlx4_ib_qp_type mlx4_ib_qp_type;
162 struct ib_umem *umem; 227 struct ib_umem *umem;
163 struct mlx4_mtt mtt; 228 struct mlx4_mtt mtt;
164 int buf_size; 229 int buf_size;
@@ -174,6 +239,8 @@ struct mlx4_ib_qp {
174 int mlx_type; 239 int mlx_type;
175 struct list_head gid_list; 240 struct list_head gid_list;
176 struct list_head steering_rules; 241 struct list_head steering_rules;
242 struct mlx4_ib_buf *sqp_proxy_rcv;
243
177}; 244};
178 245
179struct mlx4_ib_srq { 246struct mlx4_ib_srq {
@@ -196,6 +263,55 @@ struct mlx4_ib_ah {
196 union mlx4_ext_av av; 263 union mlx4_ext_av av;
197}; 264};
198 265
266struct mlx4_ib_tun_tx_buf {
267 struct mlx4_ib_buf buf;
268 struct ib_ah *ah;
269};
270
271struct mlx4_ib_demux_pv_qp {
272 struct ib_qp *qp;
273 enum ib_qp_type proxy_qpt;
274 struct mlx4_ib_buf *ring;