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 /include/rdma/ib_addr.h | |
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 'include/rdma/ib_addr.h')
-rw-r--r-- | include/rdma/ib_addr.h | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index 904ffa92fc93..b5fc9f39122b 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/if_arp.h> | 39 | #include <linux/if_arp.h> |
40 | #include <linux/netdevice.h> | 40 | #include <linux/netdevice.h> |
41 | #include <linux/socket.h> | 41 | #include <linux/socket.h> |
42 | #include <linux/if_vlan.h> | ||
42 | #include <rdma/ib_verbs.h> | 43 | #include <rdma/ib_verbs.h> |
43 | #include <rdma/ib_pack.h> | 44 | #include <rdma/ib_pack.h> |
44 | 45 | ||
@@ -129,21 +130,41 @@ static inline int rdma_addr_gid_offset(struct rdma_dev_addr *dev_addr) | |||
129 | return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0; | 130 | return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0; |
130 | } | 131 | } |
131 | 132 | ||
132 | static inline void iboe_mac_to_ll(union ib_gid *gid, u8 *mac) | 133 | static inline void iboe_mac_vlan_to_ll(union ib_gid *gid, u8 *mac, u16 vid) |
133 | { | 134 | { |
134 | memset(gid->raw, 0, 16); | 135 | memset(gid->raw, 0, 16); |
135 | *((__be32 *) gid->raw) = cpu_to_be32(0xfe800000); | 136 | *((__be32 *) gid->raw) = cpu_to_be32(0xfe800000); |
136 | gid->raw[12] = 0xfe; | 137 | if (vid < 0x1000) { |
137 | gid->raw[11] = 0xff; | 138 | gid->raw[12] = vid & 0xff; |
139 | gid->raw[11] = vid >> 8; | ||
140 | } else { | ||
141 | gid->raw[12] = 0xfe; | ||
142 | gid->raw[11] = 0xff; | ||
143 | } | ||
138 | memcpy(gid->raw + 13, mac + 3, 3); | 144 | memcpy(gid->raw + 13, mac + 3, 3); |
139 | memcpy(gid->raw + 8, mac, 3); | 145 | memcpy(gid->raw + 8, mac, 3); |
140 | gid->raw[8] ^= 2; | 146 | gid->raw[8] ^= 2; |
141 | } | 147 | } |
142 | 148 | ||
149 | static inline u16 rdma_vlan_dev_vlan_id(const struct net_device *dev) | ||
150 | { | ||
151 | return dev->priv_flags & IFF_802_1Q_VLAN ? | ||
152 | vlan_dev_vlan_id(dev) : 0xffff; | ||
153 | } | ||
154 | |||
143 | static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr, | 155 | static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr, |
144 | union ib_gid *gid) | 156 | union ib_gid *gid) |
145 | { | 157 | { |
146 | iboe_mac_to_ll(gid, dev_addr->src_dev_addr); | 158 | struct net_device *dev; |
159 | u16 vid = 0xffff; | ||
160 | |||
161 | dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); | ||
162 | if (dev) { | ||
163 | vid = rdma_vlan_dev_vlan_id(dev); | ||
164 | dev_put(dev); | ||
165 | } | ||
166 | |||
167 | iboe_mac_vlan_to_ll(gid, dev_addr->src_dev_addr, vid); | ||
147 | } | 168 | } |
148 | 169 | ||
149 | static inline void rdma_addr_get_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) | 170 | static inline void rdma_addr_get_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) |
@@ -244,4 +265,18 @@ static inline void rdma_get_mcast_mac(struct in6_addr *addr, u8 *mac) | |||
244 | mac[i] = addr->s6_addr[i + 10]; | 265 | mac[i] = addr->s6_addr[i + 10]; |
245 | } | 266 | } |
246 | 267 | ||
268 | static inline u16 rdma_get_vlan_id(union ib_gid *dgid) | ||
269 | { | ||
270 | u16 vid; | ||
271 | |||
272 | vid = dgid->raw[11] << 8 | dgid->raw[12]; | ||
273 | return vid < 0x1000 ? vid : 0xffff; | ||
274 | } | ||
275 | |||
276 | static inline struct net_device *rdma_vlan_dev_real_dev(const struct net_device *dev) | ||
277 | { | ||
278 | return dev->priv_flags & IFF_802_1Q_VLAN ? | ||
279 | vlan_dev_real_dev(dev) : 0; | ||
280 | } | ||
281 | |||
247 | #endif /* IB_ADDR_H */ | 282 | #endif /* IB_ADDR_H */ |