aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/ud_header.c
diff options
context:
space:
mode:
authorEli Cohen <eli@dev.mellanox.co.il>2010-08-26 10:18:59 -0400
committerRoland Dreier <rolandd@cisco.com>2010-10-25 13:20:39 -0400
commitaf7bd463761c6abd8ca8d831f9cc0ac19f3b7d4b (patch)
tree65d997130a892b0da260e308919ed67255a16f77 /drivers/infiniband/core/ud_header.c
parentfa417f7b520ee60b39f7e23528d2030af30a07d1 (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.c23
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
107static 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
106static const struct ib_field grh_table[] = { 118static 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[] = {
212void ib_ud_header_init(int payload_bytes, 225void 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);