diff options
author | Eli Cohen <eli@dev.mellanox.co.il> | 2010-08-26 10:18:59 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2010-10-25 13:20:39 -0400 |
commit | af7bd463761c6abd8ca8d831f9cc0ac19f3b7d4b (patch) | |
tree | 65d997130a892b0da260e308919ed67255a16f77 /drivers/infiniband/core/ud_header.c | |
parent | fa417f7b520ee60b39f7e23528d2030af30a07d1 (diff) |
IB/core: Add VLAN support for IBoE
Add 802.1q VLAN support to IBoE. The VLAN tag is encoded within the
GID derived from a link local address in the following way:
GID[11] GID[12] contain the VLAN ID when the GID contains a VLAN.
The 3 bits user priority field of the packets are identical to the 3
bits of the SL.
In case of rdma_cm apps, the TOS field is used to generate the SL
field by doing a shift right of 5 bits effectively taking to 3 MS bits
of the TOS field.
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/core/ud_header.c')
-rw-r--r-- | drivers/infiniband/core/ud_header.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c index cb0dd5ae2777..bb7e19280821 100644 --- a/drivers/infiniband/core/ud_header.c +++ b/drivers/infiniband/core/ud_header.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
36 | #include <linux/if_ether.h> | ||
36 | 37 | ||
37 | #include <rdma/ib_pack.h> | 38 | #include <rdma/ib_pack.h> |
38 | 39 | ||
@@ -103,6 +104,17 @@ static const struct ib_field eth_table[] = { | |||
103 | .size_bits = 16 } | 104 | .size_bits = 16 } |
104 | }; | 105 | }; |
105 | 106 | ||
107 | static const struct ib_field vlan_table[] = { | ||
108 | { STRUCT_FIELD(vlan, tag), | ||
109 | .offset_words = 0, | ||
110 | .offset_bits = 0, | ||
111 | .size_bits = 16 }, | ||
112 | { STRUCT_FIELD(vlan, type), | ||
113 | .offset_words = 0, | ||
114 | .offset_bits = 16, | ||
115 | .size_bits = 16 } | ||
116 | }; | ||
117 | |||
106 | static const struct ib_field grh_table[] = { | 118 | static const struct ib_field grh_table[] = { |
107 | { STRUCT_FIELD(grh, ip_version), | 119 | { STRUCT_FIELD(grh, ip_version), |
108 | .offset_words = 0, | 120 | .offset_words = 0, |
@@ -205,6 +217,7 @@ static const struct ib_field deth_table[] = { | |||
205 | * @payload_bytes:Length of packet payload | 217 | * @payload_bytes:Length of packet payload |
206 | * @lrh_present: specify if LRH is present | 218 | * @lrh_present: specify if LRH is present |
207 | * @eth_present: specify if Eth header is present | 219 | * @eth_present: specify if Eth header is present |
220 | * @vlan_present: packet is tagged vlan | ||
208 | * @grh_present:GRH flag (if non-zero, GRH will be included) | 221 | * @grh_present:GRH flag (if non-zero, GRH will be included) |
209 | * @immediate_present: specify if immediate data is present | 222 | * @immediate_present: specify if immediate data is present |
210 | * @header:Structure to initialize | 223 | * @header:Structure to initialize |
@@ -212,6 +225,7 @@ static const struct ib_field deth_table[] = { | |||
212 | void ib_ud_header_init(int payload_bytes, | 225 | void ib_ud_header_init(int payload_bytes, |
213 | int lrh_present, | 226 | int lrh_present, |
214 | int eth_present, | 227 | int eth_present, |
228 | int vlan_present, | ||
215 | int grh_present, | 229 | int grh_present, |
216 | int immediate_present, | 230 | int immediate_present, |
217 | struct ib_ud_header *header) | 231 | struct ib_ud_header *header) |
@@ -234,6 +248,9 @@ void ib_ud_header_init(int payload_bytes, | |||
234 | header->lrh.packet_length = cpu_to_be16(packet_length); | 248 | header->lrh.packet_length = cpu_to_be16(packet_length); |
235 | } | 249 | } |
236 | 250 | ||
251 | if (vlan_present) | ||
252 | header->eth.type = cpu_to_be16(ETH_P_8021Q); | ||
253 | |||
237 | if (grh_present) { | 254 | if (grh_present) { |
238 | header->grh.ip_version = 6; | 255 | header->grh.ip_version = 6; |
239 | header->grh.payload_length = | 256 | header->grh.payload_length = |
@@ -254,6 +271,7 @@ void ib_ud_header_init(int payload_bytes, | |||
254 | 271 | ||
255 | header->lrh_present = lrh_present; | 272 | header->lrh_present = lrh_present; |
256 | header->eth_present = eth_present; | 273 | header->eth_present = eth_present; |
274 | header->vlan_present = vlan_present; | ||
257 | header->grh_present = grh_present; | 275 | header->grh_present = grh_present; |
258 | header->immediate_present = immediate_present; | 276 | header->immediate_present = immediate_present; |
259 | } | 277 | } |
@@ -312,6 +330,11 @@ int ib_ud_header_pack(struct ib_ud_header *header, | |||
312 | &header->eth, buf + len); | 330 | &header->eth, buf + len); |
313 | len += IB_ETH_BYTES; | 331 | len += IB_ETH_BYTES; |
314 | } | 332 | } |
333 | if (header->vlan_present) { | ||
334 | ib_pack(vlan_table, ARRAY_SIZE(vlan_table), | ||
335 | &header->vlan, buf + len); | ||
336 | len += IB_VLAN_BYTES; | ||
337 | } | ||
315 | if (header->grh_present) { | 338 | if (header->grh_present) { |
316 | ib_pack(grh_table, ARRAY_SIZE(grh_table), | 339 | ib_pack(grh_table, ARRAY_SIZE(grh_table), |
317 | &header->grh, buf + len); | 340 | &header->grh, buf + len); |