diff options
Diffstat (limited to 'include/rdma/ib_addr.h')
-rw-r--r-- | include/rdma/ib_addr.h | 135 |
1 files changed, 134 insertions, 1 deletions
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index fa0d52b8e622..ae8c68f30f1b 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h | |||
@@ -39,7 +39,9 @@ | |||
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> |
44 | #include <rdma/ib_pack.h> | ||
43 | 45 | ||
44 | struct rdma_addr_client { | 46 | struct rdma_addr_client { |
45 | atomic_t refcount; | 47 | atomic_t refcount; |
@@ -63,6 +65,7 @@ struct rdma_dev_addr { | |||
63 | unsigned char broadcast[MAX_ADDR_LEN]; | 65 | unsigned char broadcast[MAX_ADDR_LEN]; |
64 | unsigned short dev_type; | 66 | unsigned short dev_type; |
65 | int bound_dev_if; | 67 | int bound_dev_if; |
68 | enum rdma_transport_type transport; | ||
66 | }; | 69 | }; |
67 | 70 | ||
68 | /** | 71 | /** |
@@ -127,9 +130,51 @@ static inline int rdma_addr_gid_offset(struct rdma_dev_addr *dev_addr) | |||
127 | return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0; | 130 | return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0; |
128 | } | 131 | } |
129 | 132 | ||
133 | static inline void iboe_mac_vlan_to_ll(union ib_gid *gid, u8 *mac, u16 vid) | ||
134 | { | ||
135 | memset(gid->raw, 0, 16); | ||
136 | *((__be32 *) gid->raw) = cpu_to_be32(0xfe800000); | ||
137 | if (vid < 0x1000) { | ||
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 | } | ||
144 | memcpy(gid->raw + 13, mac + 3, 3); | ||
145 | memcpy(gid->raw + 8, mac, 3); | ||
146 | gid->raw[8] ^= 2; | ||
147 | } | ||
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 | |||
155 | static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr, | ||
156 | union ib_gid *gid) | ||
157 | { | ||
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); | ||
168 | } | ||
169 | |||
130 | 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) |
131 | { | 171 | { |
132 | memcpy(gid, dev_addr->src_dev_addr + rdma_addr_gid_offset(dev_addr), sizeof *gid); | 172 | if (dev_addr->transport == RDMA_TRANSPORT_IB && |
173 | dev_addr->dev_type != ARPHRD_INFINIBAND) | ||
174 | iboe_addr_get_sgid(dev_addr, gid); | ||
175 | else | ||
176 | memcpy(gid, dev_addr->src_dev_addr + | ||
177 | rdma_addr_gid_offset(dev_addr), sizeof *gid); | ||
133 | } | 178 | } |
134 | 179 | ||
135 | static inline void rdma_addr_set_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) | 180 | static inline void rdma_addr_set_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) |
@@ -147,4 +192,92 @@ static inline void rdma_addr_set_dgid(struct rdma_dev_addr *dev_addr, union ib_g | |||
147 | memcpy(dev_addr->dst_dev_addr + rdma_addr_gid_offset(dev_addr), gid, sizeof *gid); | 192 | memcpy(dev_addr->dst_dev_addr + rdma_addr_gid_offset(dev_addr), gid, sizeof *gid); |
148 | } | 193 | } |
149 | 194 | ||
195 | static inline enum ib_mtu iboe_get_mtu(int mtu) | ||
196 | { | ||
197 | /* | ||
198 | * reduce IB headers from effective IBoE MTU. 28 stands for | ||
199 | * atomic header which is the biggest possible header after BTH | ||
200 | */ | ||
201 | mtu = mtu - IB_GRH_BYTES - IB_BTH_BYTES - 28; | ||
202 | |||
203 | if (mtu >= ib_mtu_enum_to_int(IB_MTU_4096)) | ||
204 | return IB_MTU_4096; | ||
205 | else if (mtu >= ib_mtu_enum_to_int(IB_MTU_2048)) | ||
206 | return IB_MTU_2048; | ||
207 | else if (mtu >= ib_mtu_enum_to_int(IB_MTU_1024)) | ||
208 | return IB_MTU_1024; | ||
209 | else if (mtu >= ib_mtu_enum_to_int(IB_MTU_512)) | ||
210 | return IB_MTU_512; | ||
211 | else if (mtu >= ib_mtu_enum_to_int(IB_MTU_256)) | ||
212 | return IB_MTU_256; | ||
213 | else | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static inline int iboe_get_rate(struct net_device *dev) | ||
218 | { | ||
219 | struct ethtool_cmd cmd; | ||
220 | u32 speed; | ||
221 | |||
222 | if (dev_ethtool_get_settings(dev, &cmd)) | ||
223 | return IB_RATE_PORT_CURRENT; | ||
224 | |||
225 | speed = ethtool_cmd_speed(&cmd); | ||
226 | if (speed >= 40000) | ||
227 | return IB_RATE_40_GBPS; | ||
228 | else if (speed >= 30000) | ||
229 | return IB_RATE_30_GBPS; | ||
230 | else if (speed >= 20000) | ||
231 | return IB_RATE_20_GBPS; | ||
232 | else if (speed >= 10000) | ||
233 | return IB_RATE_10_GBPS; | ||
234 | else | ||
235 | return IB_RATE_PORT_CURRENT; | ||
236 | } | ||
237 | |||
238 | static inline int rdma_link_local_addr(struct in6_addr *addr) | ||
239 | { | ||
240 | if (addr->s6_addr32[0] == htonl(0xfe800000) && | ||
241 | addr->s6_addr32[1] == 0) | ||
242 | return 1; | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static inline void rdma_get_ll_mac(struct in6_addr *addr, u8 *mac) | ||
248 | { | ||
249 | memcpy(mac, &addr->s6_addr[8], 3); | ||
250 | memcpy(mac + 3, &addr->s6_addr[13], 3); | ||
251 | mac[0] ^= 2; | ||
252 | } | ||
253 | |||
254 | static inline int rdma_is_multicast_addr(struct in6_addr *addr) | ||
255 | { | ||
256 | return addr->s6_addr[0] == 0xff; | ||
257 | } | ||
258 | |||
259 | static inline void rdma_get_mcast_mac(struct in6_addr *addr, u8 *mac) | ||
260 | { | ||
261 | int i; | ||
262 | |||
263 | mac[0] = 0x33; | ||
264 | mac[1] = 0x33; | ||
265 | for (i = 2; i < 6; ++i) | ||
266 | mac[i] = addr->s6_addr[i + 10]; | ||
267 | } | ||
268 | |||
269 | static inline u16 rdma_get_vlan_id(union ib_gid *dgid) | ||
270 | { | ||
271 | u16 vid; | ||
272 | |||
273 | vid = dgid->raw[11] << 8 | dgid->raw[12]; | ||
274 | return vid < 0x1000 ? vid : 0xffff; | ||
275 | } | ||
276 | |||
277 | static inline struct net_device *rdma_vlan_dev_real_dev(const struct net_device *dev) | ||
278 | { | ||
279 | return dev->priv_flags & IFF_802_1Q_VLAN ? | ||
280 | vlan_dev_real_dev(dev) : 0; | ||
281 | } | ||
282 | |||
150 | #endif /* IB_ADDR_H */ | 283 | #endif /* IB_ADDR_H */ |