diff options
Diffstat (limited to 'include/rdma/ib_addr.h')
| -rw-r--r-- | include/rdma/ib_addr.h | 134 |
1 files changed, 133 insertions, 1 deletions
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index fa0d52b8e622..b5fc9f39122b 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,91 @@ 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 | |||
| 221 | if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings || | ||
| 222 | dev->ethtool_ops->get_settings(dev, &cmd)) | ||
| 223 | return IB_RATE_PORT_CURRENT; | ||
| 224 | |||
| 225 | if (cmd.speed >= 40000) | ||
| 226 | return IB_RATE_40_GBPS; | ||
| 227 | else if (cmd.speed >= 30000) | ||
| 228 | return IB_RATE_30_GBPS; | ||
| 229 | else if (cmd.speed >= 20000) | ||
| 230 | return IB_RATE_20_GBPS; | ||
| 231 | else if (cmd.speed >= 10000) | ||
| 232 | return IB_RATE_10_GBPS; | ||
| 233 | else | ||
| 234 | return IB_RATE_PORT_CURRENT; | ||
| 235 | } | ||
| 236 | |||
| 237 | static inline int rdma_link_local_addr(struct in6_addr *addr) | ||
| 238 | { | ||
| 239 | if (addr->s6_addr32[0] == htonl(0xfe800000) && | ||
| 240 | addr->s6_addr32[1] == 0) | ||
| 241 | return 1; | ||
| 242 | |||
| 243 | return 0; | ||
| 244 | } | ||
| 245 | |||
| 246 | static inline void rdma_get_ll_mac(struct in6_addr *addr, u8 *mac) | ||
| 247 | { | ||
| 248 | memcpy(mac, &addr->s6_addr[8], 3); | ||
| 249 | memcpy(mac + 3, &addr->s6_addr[13], 3); | ||
| 250 | mac[0] ^= 2; | ||
| 251 | } | ||
| 252 | |||
| 253 | static inline int rdma_is_multicast_addr(struct in6_addr *addr) | ||
| 254 | { | ||
| 255 | return addr->s6_addr[0] == 0xff; | ||
| 256 | } | ||
| 257 | |||
| 258 | static inline void rdma_get_mcast_mac(struct in6_addr *addr, u8 *mac) | ||
| 259 | { | ||
| 260 | int i; | ||
| 261 | |||
| 262 | mac[0] = 0x33; | ||
| 263 | mac[1] = 0x33; | ||
| 264 | for (i = 2; i < 6; ++i) | ||
| 265 | mac[i] = addr->s6_addr[i + 10]; | ||
| 266 | } | ||
| 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 | |||
| 150 | #endif /* IB_ADDR_H */ | 282 | #endif /* IB_ADDR_H */ |
