aboutsummaryrefslogtreecommitdiffstats
path: root/include/rdma
diff options
context:
space:
mode:
authorEli Cohen <eli@dev.mellanox.co.il>2010-10-13 15:26:51 -0400
committerRoland Dreier <rolandd@cisco.com>2010-10-13 18:46:43 -0400
commit3c86aa70bf677a31b71c8292e349242e26cbc743 (patch)
tree7f38edd826e444b1232185e154f313e70966d250 /include/rdma
parentfac70d51914674ce8ae742ed73441ddb4770ad20 (diff)
RDMA/cm: Add RDMA CM support for IBoE devices
Add support for IBoE device binding and IP --> GID resolution. Path resolving and multicast joining are implemented within cma.c by filling in the responses and running callbacks in the CMA work queue. IP --> GID resolution always yields IPv6 link local addresses; remote GIDs are derived from the destination MAC address of the remote port. Multicast GIDs are always mapped to multicast MACs as is done in IPv6. (IPv4 multicast is enabled by translating IPv4 multicast addresses to IPv6 multicast as described in <http://www.mail-archive.com/ipng@sunroof.eng.sun.com/msg02134.html>.) Some helper functions are added to ib_addr.h. Signed-off-by: Eli Cohen <eli@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'include/rdma')
-rw-r--r--include/rdma/ib_addr.h99
1 files changed, 98 insertions, 1 deletions
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index fa0d52b8e622..904ffa92fc93 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -40,6 +40,7 @@
40#include <linux/netdevice.h> 40#include <linux/netdevice.h>
41#include <linux/socket.h> 41#include <linux/socket.h>
42#include <rdma/ib_verbs.h> 42#include <rdma/ib_verbs.h>
43#include <rdma/ib_pack.h>
43 44
44struct rdma_addr_client { 45struct rdma_addr_client {
45 atomic_t refcount; 46 atomic_t refcount;
@@ -63,6 +64,7 @@ struct rdma_dev_addr {
63 unsigned char broadcast[MAX_ADDR_LEN]; 64 unsigned char broadcast[MAX_ADDR_LEN];
64 unsigned short dev_type; 65 unsigned short dev_type;
65 int bound_dev_if; 66 int bound_dev_if;
67 enum rdma_transport_type transport;
66}; 68};
67 69
68/** 70/**
@@ -127,9 +129,31 @@ static inline int rdma_addr_gid_offset(struct rdma_dev_addr *dev_addr)
127 return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0; 129 return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0;
128} 130}
129 131
132static inline void iboe_mac_to_ll(union ib_gid *gid, u8 *mac)
133{
134 memset(gid->raw, 0, 16);
135 *((__be32 *) gid->raw) = cpu_to_be32(0xfe800000);
136 gid->raw[12] = 0xfe;
137 gid->raw[11] = 0xff;
138 memcpy(gid->raw + 13, mac + 3, 3);
139 memcpy(gid->raw + 8, mac, 3);
140 gid->raw[8] ^= 2;
141}
142
143static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr,
144 union ib_gid *gid)
145{
146 iboe_mac_to_ll(gid, dev_addr->src_dev_addr);
147}
148
130static inline void rdma_addr_get_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) 149static inline void rdma_addr_get_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid)
131{ 150{
132 memcpy(gid, dev_addr->src_dev_addr + rdma_addr_gid_offset(dev_addr), sizeof *gid); 151 if (dev_addr->transport == RDMA_TRANSPORT_IB &&
152 dev_addr->dev_type != ARPHRD_INFINIBAND)
153 iboe_addr_get_sgid(dev_addr, gid);
154 else
155 memcpy(gid, dev_addr->src_dev_addr +
156 rdma_addr_gid_offset(dev_addr), sizeof *gid);
133} 157}
134 158
135static inline void rdma_addr_set_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) 159static inline void rdma_addr_set_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid)
@@ -147,4 +171,77 @@ 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); 171 memcpy(dev_addr->dst_dev_addr + rdma_addr_gid_offset(dev_addr), gid, sizeof *gid);
148} 172}
149 173
174static inline enum ib_mtu iboe_get_mtu(int mtu)
175{
176 /*
177 * reduce IB headers from effective IBoE MTU. 28 stands for
178 * atomic header which is the biggest possible header after BTH
179 */
180 mtu = mtu - IB_GRH_BYTES - IB_BTH_BYTES - 28;
181
182 if (mtu >= ib_mtu_enum_to_int(IB_MTU_4096))
183 return IB_MTU_4096;
184 else if (mtu >= ib_mtu_enum_to_int(IB_MTU_2048))
185 return IB_MTU_2048;
186 else if (mtu >= ib_mtu_enum_to_int(IB_MTU_1024))
187 return IB_MTU_1024;
188 else if (mtu >= ib_mtu_enum_to_int(IB_MTU_512))
189 return IB_MTU_512;
190 else if (mtu >= ib_mtu_enum_to_int(IB_MTU_256))
191 return IB_MTU_256;
192 else
193 return 0;
194}
195
196static inline int iboe_get_rate(struct net_device *dev)
197{
198 struct ethtool_cmd cmd;
199
200 if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings ||
201 dev->ethtool_ops->get_settings(dev, &cmd))
202 return IB_RATE_PORT_CURRENT;
203
204 if (cmd.speed >= 40000)
205 return IB_RATE_40_GBPS;
206 else if (cmd.speed >= 30000)
207 return IB_RATE_30_GBPS;
208 else if (cmd.speed >= 20000)
209 return IB_RATE_20_GBPS;
210 else if (cmd.speed >= 10000)
211 return IB_RATE_10_GBPS;
212 else
213 return IB_RATE_PORT_CURRENT;
214}
215
216static inline int rdma_link_local_addr(struct in6_addr *addr)
217{
218 if (addr->s6_addr32[0] == htonl(0xfe800000) &&
219 addr->s6_addr32[1] == 0)
220 return 1;
221
222 return 0;
223}
224
225static inline void rdma_get_ll_mac(struct in6_addr *addr, u8 *mac)
226{
227 memcpy(mac, &addr->s6_addr[8], 3);
228 memcpy(mac + 3, &addr->s6_addr[13], 3);
229 mac[0] ^= 2;
230}
231
232static inline int rdma_is_multicast_addr(struct in6_addr *addr)
233{
234 return addr->s6_addr[0] == 0xff;
235}
236
237static inline void rdma_get_mcast_mac(struct in6_addr *addr, u8 *mac)
238{
239 int i;
240
241 mac[0] = 0x33;
242 mac[1] = 0x33;
243 for (i = 2; i < 6; ++i)
244 mac[i] = addr->s6_addr[i + 10];
245}
246
150#endif /* IB_ADDR_H */ 247#endif /* IB_ADDR_H */