diff options
| author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2012-08-03 04:40:40 -0400 |
|---|---|---|
| committer | Roland Dreier <roland@purestorage.com> | 2012-09-30 23:33:30 -0400 |
| commit | 1ffeb2eb8be9936e9dc1f9af2d5f4c14d69a0d36 (patch) | |
| tree | 1e79a4a6c3955a21c7802618d58b3bd7605a937e | |
| parent | 73aaa7418f8069103ca56fc620b3cd16c5a37d6e (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.c | 31 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/mlx4_ib.h | 128 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 616 | ||||
| -rw-r--r-- | include/linux/mlx4/device.h | 1 | ||||
| -rw-r--r-- | include/linux/mlx4/qp.h | 3 |
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 | ||
| 550 | static 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 | |||
| 550 | static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, | 570 | static 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 | ||
| 563 | repoll: | 584 | repoll: |
| 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 | ||
| 135 | enum mlx4_ib_qp_flags { | 135 | enum 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 | ||
| 140 | struct mlx4_ib_gid_entry { | 142 | struct mlx4_ib_gid_entry { |
| @@ -144,6 +146,68 @@ struct mlx4_ib_gid_entry { | |||
| 144 | u8 port; | 146 | u8 port; |
| 145 | }; | 147 | }; |
| 146 | 148 | ||
| 149 | enum 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 | |||
| 179 | struct 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 | |||
| 189 | struct mlx4_ib_buf { | ||
| 190 | void *addr; | ||
| 191 | dma_addr_t map; | ||
| 192 | }; | ||
| 193 | |||
| 194 | struct 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 | |||
| 206 | struct mlx4_ib_proxy_sqp_hdr { | ||
| 207 | struct ib_grh grh; | ||
| 208 | struct mlx4_rcv_tunnel_hdr tun; | ||
| 209 | } __packed; | ||
| 210 | |||
| 147 | struct mlx4_ib_qp { | 211 | struct 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 | ||
| 179 | struct mlx4_ib_srq { | 246 | struct 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 | ||
| 266 | struct mlx4_ib_tun_tx_buf { | ||
| 267 | struct mlx4_ib_buf buf; | ||
| 268 | struct ib_ah *ah; | ||
| 269 | }; | ||
| 270 | |||
| 271 | struct mlx4_ib_demux_pv_qp { | ||
| 272 | struct ib_qp *qp; | ||
| 273 | enum ib_qp_type proxy_qpt; | ||
| 274 | struct mlx4_ib_buf *ring; | ||
