#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <byteswap.h>
#include <errno.h>
#include <gpxe/errortab.h>
#include <gpxe/if_arp.h>
#include <gpxe/iobuf.h>
#include <gpxe/netdevice.h>
#include <gpxe/infiniband.h>
#include <gpxe/ib_pathrec.h>
#include <gpxe/ib_mcast.h>
#include <gpxe/ipoib.h>
Go to the source code of this file.
Data Structures | |
| struct | ipoib_device |
| An IPoIB device. More... | |
| struct | ipoib_peer |
| IPoIB peer address. More... | |
| struct | ipoib_eth_addr_handler |
| An IPoIB Ethernet-compatible compressed link-layer address generator. More... | |
Defines | |
| #define | IPOIB_NUM_SEND_WQES 2 |
| Number of IPoIB send work queue entries. | |
| #define | IPOIB_NUM_RECV_WQES 4 |
| Number of IPoIB receive work queue entries. | |
| #define | IPOIB_NUM_CQES 8 |
| Number of IPoIB completion entries. | |
| #define | EINPROGRESS_JOINING ( EINPROGRESS | EUNIQ_01 ) |
| Link status for "broadcast join in progress". | |
| #define | IPOIB_NUM_CACHED_PEERS 4 |
| Number of IPoIB peer cache entries. | |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static struct ipoib_peer * | ipoib_lookup_peer_by_key (unsigned int key) |
| Look up cached peer by key. | |
| static struct ipoib_peer * | ipoib_cache_peer (const struct ipoib_mac *mac) |
| Store GID and QPN in peer cache. | |
| static int | ipoib_push (struct net_device *netdev __unused, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source __unused, uint16_t net_proto) |
| Add IPoIB link-layer header. | |
| static int | ipoib_pull (struct net_device *netdev, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto) |
| Remove IPoIB link-layer header. | |
| static void | ipoib_init_addr (const void *hw_addr, void *ll_addr) |
| Initialise IPoIB link-layer address. | |
| const char * | ipoib_ntoa (const void *ll_addr) |
| Transcribe IPoIB link-layer address. | |
| static int | ipoib_mc_hash (unsigned int af __unused, const void *net_addr __unused, void *ll_addr __unused) |
| Hash multicast address. | |
| static int | ipoib_mlx_eth_addr (const struct ib_gid_half *guid, uint8_t *eth_addr) |
| Generate Mellanox Ethernet-compatible compressed link-layer address. | |
| static int | ipoib_eth_addr (const void *ll_addr, void *eth_addr) |
| Generate Ethernet-compatible compressed link-layer address. | |
| struct net_device * | alloc_ipoibdev (size_t priv_size) |
| Allocate IPoIB device. | |
| static int | ipoib_transmit (struct net_device *netdev, struct io_buffer *iobuf) |
| Transmit packet via IPoIB network device. | |
| static void | ipoib_complete_send (struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc) |
| Handle IPoIB send completion. | |
| static void | ipoib_complete_recv (struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, int rc) |
| Handle IPoIB receive completion. | |
| static void | ipoib_poll (struct net_device *netdev) |
| Poll IPoIB network device. | |
| static void | ipoib_irq (struct net_device *netdev __unused, int enable __unused) |
| Enable/disable interrupts on IPoIB network device. | |
| void | ipoib_join_complete (struct ib_device *ibdev __unused, struct ib_queue_pair *qp __unused, struct ib_mc_membership *membership, int rc, union ib_mad *mad __unused) |
| Handle IPv4 broadcast multicast group join completion. | |
| static int | ipoib_join_broadcast_group (struct ipoib_device *ipoib) |
| Join IPv4 broadcast multicast group. | |
| static void | ipoib_leave_broadcast_group (struct ipoib_device *ipoib) |
| Leave IPv4 broadcast multicast group. | |
| static int | ipoib_open (struct net_device *netdev) |
| Open IPoIB network device. | |
| static void | ipoib_close (struct net_device *netdev) |
| Close IPoIB network device. | |
| void | ipoib_link_state_changed (struct ib_device *ibdev) |
| Handle link status change. | |
| int | ipoib_probe (struct ib_device *ibdev) |
| Probe IPoIB device. | |
| void | ipoib_remove (struct ib_device *ibdev) |
| Remove IPoIB device. | |
Variables | |
| static struct ipoib_mac | ipoib_broadcast |
| Broadcast IPoIB address. | |
| struct errortab ipoib_errors[] | __errortab |
| Human-readable message for the link status. | |
| static struct ipoib_peer | ipoib_peer_cache [IPOIB_NUM_CACHED_PEERS] |
| IPoIB peer address cache. | |
| static unsigned int | ipoib_peer_cache_idx = 1 |
| Oldest IPoIB peer cache entry index. | |
| static struct ipoib_eth_addr_handler | ipoib_eth_addr_handlers [] |
| IPoIB Ethernet-compatible compressed link-layer address generators. | |
| struct ll_protocol ipoib_protocol | __ll_protocol |
| IPoIB protocol. | |
| static struct ib_completion_queue_operations | ipoib_cq_op |
| IPoIB completion operations. | |
| static struct net_device_operations | ipoib_operations |
| IPoIB network device operations. | |
Definition in file ipoib.c.
| #define IPOIB_NUM_SEND_WQES 2 |
Number of IPoIB send work queue entries.
Definition at line 42 of file ipoib.c.
Referenced by ipoib_open().
| #define IPOIB_NUM_RECV_WQES 4 |
Number of IPoIB receive work queue entries.
Definition at line 45 of file ipoib.c.
Referenced by ipoib_open().
| #define IPOIB_NUM_CQES 8 |
Number of IPoIB completion entries.
Definition at line 48 of file ipoib.c.
Referenced by ipoib_open().
| #define EINPROGRESS_JOINING ( EINPROGRESS | EUNIQ_01 ) |
Link status for "broadcast join in progress".
Definition at line 80 of file ipoib.c.
Referenced by ipoib_link_state_changed().
| #define IPOIB_NUM_CACHED_PEERS 4 |
Number of IPoIB peer cache entries.
Must be a power of two.
Definition at line 115 of file ipoib.c.
Referenced by ipoib_cache_peer(), and ipoib_lookup_peer_by_key().
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static struct ipoib_peer* ipoib_lookup_peer_by_key | ( | unsigned int | key | ) | [static, read] |
Look up cached peer by key.
| key | Peer cache key |
| peer | Peer cache entry, or NULL |
Definition at line 129 of file ipoib.c.
References DBG, IPOIB_NUM_CACHED_PEERS, ipoib_peer_cache, ipoib_peer::key, and NULL.
Referenced by ipoib_pull(), and ipoib_transmit().
00129 { 00130 struct ipoib_peer *peer; 00131 unsigned int i; 00132 00133 for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) { 00134 peer = &ipoib_peer_cache[i]; 00135 if ( peer->key == key ) 00136 return peer; 00137 } 00138 00139 if ( key != 0 ) { 00140 DBG ( "IPoIB warning: peer cache lost track of key %x while " 00141 "still in use\n", key ); 00142 } 00143 return NULL; 00144 }
| static struct ipoib_peer* ipoib_cache_peer | ( | const struct ipoib_mac * | mac | ) | [static, read] |
Store GID and QPN in peer cache.
| mac | Peer MAC address |
| peer | Peer cache entry |
Definition at line 152 of file ipoib.c.
References DBG, ipoib_ntoa(), IPOIB_NUM_CACHED_PEERS, ipoib_peer_cache, ipoib_peer_cache_idx, ipoib_peer::key, ipoib_peer::mac, memcmp(), memcpy, and memset().
Referenced by ipoib_complete_recv(), and ipoib_push().
00152 { 00153 struct ipoib_peer *peer; 00154 unsigned int key; 00155 unsigned int i; 00156 00157 /* Look for existing cache entry */ 00158 for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) { 00159 peer = &ipoib_peer_cache[i]; 00160 if ( memcmp ( &peer->mac, mac, sizeof ( peer->mac ) ) == 0 ) 00161 return peer; 00162 } 00163 00164 /* No entry found: create a new one */ 00165 key = ipoib_peer_cache_idx++; 00166 peer = &ipoib_peer_cache[ key % IPOIB_NUM_CACHED_PEERS ]; 00167 if ( peer->key ) 00168 DBG ( "IPoIB peer %x evicted from cache\n", peer->key ); 00169 00170 memset ( peer, 0, sizeof ( *peer ) ); 00171 peer->key = key; 00172 memcpy ( &peer->mac, mac, sizeof ( peer->mac ) ); 00173 DBG ( "IPoIB peer %x has MAC %s\n", 00174 peer->key, ipoib_ntoa ( &peer->mac ) ); 00175 return peer; 00176 }
| static int ipoib_push | ( | struct net_device *netdev | __unused, | |
| struct io_buffer * | iobuf, | |||
| const void * | ll_dest, | |||
| const void *ll_source | __unused, | |||
| uint16_t | net_proto | |||
| ) | [static] |
Add IPoIB link-layer header.
| netdev | Network device | |
| iobuf | I/O buffer | |
| ll_dest | Link-layer destination address | |
| ll_source | Source link-layer address | |
| net_proto | Network-layer protocol, in network-byte order |
| rc | Return status code |
Definition at line 195 of file ipoib.c.
References dest, iob_push, ipoib_cache_peer(), ipoib_peer::key, ipoib_hdr::peer, ipoib_hdr::proto, src, and ipoib_hdr::u.
00197 { 00198 struct ipoib_hdr *ipoib_hdr = 00199 iob_push ( iobuf, sizeof ( *ipoib_hdr ) ); 00200 const struct ipoib_mac *dest_mac = ll_dest; 00201 const struct ipoib_mac *src_mac = ll_source; 00202 struct ipoib_peer *dest; 00203 struct ipoib_peer *src; 00204 00205 /* Add link-layer addresses to cache */ 00206 dest = ipoib_cache_peer ( dest_mac ); 00207 src = ipoib_cache_peer ( src_mac ); 00208 00209 /* Build IPoIB header */ 00210 ipoib_hdr->proto = net_proto; 00211 ipoib_hdr->u.peer.dest = dest->key; 00212 ipoib_hdr->u.peer.src = src->key; 00213 00214 return 0; 00215 }
| static int ipoib_pull | ( | struct net_device * | netdev, | |
| struct io_buffer * | iobuf, | |||
| const void ** | ll_dest, | |||
| const void ** | ll_source, | |||
| uint16_t * | net_proto | |||
| ) | [static] |
Remove IPoIB link-layer header.
| netdev | Network device | |
| iobuf | I/O buffer |
| ll_dest | Link-layer destination address | |
| ll_source | Source link-layer address | |
| net_proto | Network-layer protocol, in network-byte order | |
| rc | Return status code |
Definition at line 227 of file ipoib.c.
References ipoib_device::broadcast, io_buffer::data, DBG, DBG_HD, dest, EINVAL, iob_len(), iob_pull, ipoib_lookup_peer_by_key(), ipoib_peer::mac, ipoib_hdr::peer, net_device::priv, ipoib_hdr::proto, ipoib_hdr::reserved, and ipoib_hdr::u.
00229 { 00230 struct ipoib_device *ipoib = netdev->priv; 00231 struct ipoib_hdr *ipoib_hdr = iobuf->data; 00232 struct ipoib_peer *dest; 00233 struct ipoib_peer *source; 00234 00235 /* Sanity check */ 00236 if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) { 00237 DBG ( "IPoIB packet too short for link-layer header\n" ); 00238 DBG_HD ( iobuf->data, iob_len ( iobuf ) ); 00239 return -EINVAL; 00240 } 00241 00242 /* Strip off IPoIB header */ 00243 iob_pull ( iobuf, sizeof ( *ipoib_hdr ) ); 00244 00245 /* Identify source and destination addresses, and clear 00246 * reserved word in IPoIB header 00247 */ 00248 dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest ); 00249 source = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.src ); 00250 ipoib_hdr->u.reserved = 0; 00251 00252 /* Fill in required fields */ 00253 *ll_dest = ( dest ? &dest->mac : &ipoib->broadcast ); 00254 *ll_source = ( source ? &source->mac : &ipoib->broadcast ); 00255 *net_proto = ipoib_hdr->proto; 00256 00257 return 0; 00258 }
| static void ipoib_init_addr | ( | const void * | hw_addr, | |
| void * | ll_addr | |||
| ) | [static] |
Initialise IPoIB link-layer address.
| hw_addr | Hardware address | |
| ll_addr | Link-layer address |
Definition at line 266 of file ipoib.c.
References ipoib_mac::gid, ib_gid::half, memcpy, memset(), and ib_gid::u.
00266 { 00267 const struct ib_gid_half *guid = hw_addr; 00268 struct ipoib_mac *mac = ll_addr; 00269 00270 memset ( mac, 0, sizeof ( *mac ) ); 00271 memcpy ( &mac->gid.u.half[1], guid, sizeof ( mac->gid.u.half[1] ) ); 00272 }
| const char* ipoib_ntoa | ( | const void * | ll_addr | ) |
Transcribe IPoIB link-layer address.
| ll_addr | Link-layer address |
| string | Link-layer address in human-readable format |
Definition at line 280 of file ipoib.c.
References ib_gid::dwords, ipoib_mac::flags__qpn, ipoib_mac::gid, htonl, snprintf(), and ib_gid::u.
Referenced by ipoib_cache_peer().
00280 { 00281 static char buf[45]; 00282 const struct ipoib_mac *mac = ll_addr; 00283 00284 snprintf ( buf, sizeof ( buf ), "%08x:%08x:%08x:%08x:%08x", 00285 htonl ( mac->flags__qpn ), htonl ( mac->gid.u.dwords[0] ), 00286 htonl ( mac->gid.u.dwords[1] ), 00287 htonl ( mac->gid.u.dwords[2] ), 00288 htonl ( mac->gid.u.dwords[3] ) ); 00289 return buf; 00290 }
| static int ipoib_mc_hash | ( | unsigned int af | __unused, | |
| const void *net_addr | __unused, | |||
| void *ll_addr | __unused | |||
| ) | [static] |
| static int ipoib_mlx_eth_addr | ( | const struct ib_gid_half * | guid, | |
| uint8_t * | eth_addr | |||
| ) | [static] |
Generate Mellanox Ethernet-compatible compressed link-layer address.
| ll_addr | Link-layer address | |
| eth_addr | Ethernet-compatible address to fill in |
Definition at line 313 of file ipoib.c.
References ib_gid_half::bytes, and ib_gid_half::u.
00314 { 00315 eth_addr[0] = ( ( guid->u.bytes[3] == 2 ) ? 0x00 : 0x02 ); 00316 eth_addr[1] = guid->u.bytes[1]; 00317 eth_addr[2] = guid->u.bytes[2]; 00318 eth_addr[3] = guid->u.bytes[5]; 00319 eth_addr[4] = guid->u.bytes[6]; 00320 eth_addr[5] = guid->u.bytes[7]; 00321 return 0; 00322 }
| static int ipoib_eth_addr | ( | const void * | ll_addr, | |
| void * | eth_addr | |||
| ) | [static] |
Generate Ethernet-compatible compressed link-layer address.
| ll_addr | Link-layer address | |
| eth_addr | Ethernet-compatible address to fill in |
Definition at line 346 of file ipoib.c.
References ipoib_eth_addr_handler::byte1, ipoib_eth_addr_handler::byte2, ib_gid_half::bytes, ENOTSUP, ipoib_eth_addr_handler::eth_addr, ipoib_mac::gid, ib_gid::half, ib_gid_half::u, and ib_gid::u.
00346 { 00347 const struct ipoib_mac *ipoib_addr = ll_addr; 00348 const struct ib_gid_half *guid = &ipoib_addr->gid.u.half[1]; 00349 struct ipoib_eth_addr_handler *handler; 00350 unsigned int i; 00351 00352 for ( i = 0 ; i < ( sizeof ( ipoib_eth_addr_handlers ) / 00353 sizeof ( ipoib_eth_addr_handlers[0] ) ) ; i++ ) { 00354 handler = &ipoib_eth_addr_handlers[i]; 00355 if ( ( handler->byte1 == guid->u.bytes[1] ) && 00356 ( handler->byte2 == guid->u.bytes[2] ) ) { 00357 return handler->eth_addr ( guid, eth_addr ); 00358 } 00359 } 00360 return -ENOTSUP; 00361 }
| struct net_device* alloc_ipoibdev | ( | size_t | priv_size | ) | [read] |
Allocate IPoIB device.
| priv_size | Size of driver private data |
| netdev | Network device, or NULL |
Definition at line 384 of file ipoib.c.
References alloc_netdev(), IB_MAX_PAYLOAD_SIZE, net_device::ll_broadcast, net_device::ll_protocol, net_device::max_pkt_len, and netdev.
Referenced by ipoib_probe().
00384 { 00385 struct net_device *netdev; 00386 00387 netdev = alloc_netdev ( priv_size ); 00388 if ( netdev ) { 00389 netdev->ll_protocol = &ipoib_protocol; 00390 netdev->ll_broadcast = ( uint8_t * ) &ipoib_broadcast; 00391 netdev->max_pkt_len = IB_MAX_PAYLOAD_SIZE; 00392 } 00393 return netdev; 00394 }
| static int ipoib_transmit | ( | struct net_device * | netdev, | |
| struct io_buffer * | iobuf | |||
| ) | [static] |
Transmit packet via IPoIB network device.
| netdev | Network device | |
| iobuf | I/O buffer |
| rc | Return status code |
Definition at line 410 of file ipoib.c.
References io_buffer::data, DBGC, dest, EINVAL, ENETUNREACH, ENXIO, ipoib_mac::flags__qpn, ipoib_mac::gid, ib_address_vector::gid, ib_address_vector::gid_present, ib_link_ok(), ib_post_send(), IB_QPN_MASK, ib_resolve_path(), ipoib_device::ibdev, iob_len(), ipoib_lookup_peer_by_key(), ipoib_peer::mac, memcpy, memset(), ntohl, ipoib_hdr::peer, net_device::priv, ipoib_device::qp, ib_address_vector::qpn, ipoib_hdr::reserved, and ipoib_hdr::u.
00411 { 00412 struct ipoib_device *ipoib = netdev->priv; 00413 struct ib_device *ibdev = ipoib->ibdev; 00414 struct ipoib_hdr *ipoib_hdr; 00415 struct ipoib_peer *dest; 00416 struct ib_address_vector av; 00417 int rc; 00418 00419 /* Sanity check */ 00420 if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) { 00421 DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib ); 00422 return -EINVAL; 00423 } 00424 ipoib_hdr = iobuf->data; 00425 00426 /* Attempting transmission while link is down will put the 00427 * queue pair into an error state, so don't try it. 00428 */ 00429 if ( ! ib_link_ok ( ibdev ) ) 00430 return -ENETUNREACH; 00431 00432 /* Identify destination address */ 00433 dest = ipoib_lookup_peer_by_key ( ipoib_hdr->u.peer.dest ); 00434 if ( ! dest ) 00435 return -ENXIO; 00436 ipoib_hdr->u.reserved = 0; 00437 00438 /* Construct address vector */ 00439 memset ( &av, 0, sizeof ( av ) ); 00440 av.qpn = ( ntohl ( dest->mac.flags__qpn ) & IB_QPN_MASK ); 00441 av.gid_present = 1; 00442 memcpy ( &av.gid, &dest->mac.gid, sizeof ( av.gid ) ); 00443 if ( ( rc = ib_resolve_path ( ibdev, &av ) ) != 0 ) { 00444 /* Path not resolved yet */ 00445 return rc; 00446 } 00447 00448 return ib_post_send ( ibdev, ipoib->qp, &av, iobuf ); 00449 }
| static void ipoib_complete_send | ( | struct ib_device *ibdev | __unused, | |
| struct ib_queue_pair * | qp, | |||
| struct io_buffer * | iobuf, | |||
| int | rc | |||
| ) | [static] |
Handle IPoIB send completion.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| iobuf | I/O buffer | |
| rc | Completion status code |
Definition at line 459 of file ipoib.c.
References ib_qp_get_ownerdata(), ipoib_device::netdev, and netdev_tx_complete_err().
00461 { 00462 struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp ); 00463 00464 netdev_tx_complete_err ( ipoib->netdev, iobuf, rc ); 00465 }
| static void ipoib_complete_recv | ( | struct ib_device *ibdev | __unused, | |
| struct ib_queue_pair * | qp, | |||
| struct ib_address_vector * | av, | |||
| struct io_buffer * | iobuf, | |||
| int | rc | |||
| ) | [static] |
Handle IPoIB receive completion.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| av | Address vector, or NULL | |
| iobuf | I/O buffer | |
| rc | Completion status code |
Definition at line 476 of file ipoib.c.
References io_buffer::data, DBGC, DBGC_HD, EIO, ipoib_mac::flags__qpn, ib_address_vector::gid, ipoib_mac::gid, ib_address_vector::gid_present, htonl, ib_qp_get_ownerdata(), iob_len(), ipoib_cache_peer(), ipoib_peer::key, memcpy, ipoib_device::netdev, netdev, netdev_rx(), netdev_rx_err(), ipoib_hdr::peer, ib_address_vector::qpn, src, and ipoib_hdr::u.
00479 { 00480 struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp ); 00481 struct net_device *netdev = ipoib->netdev; 00482 struct ipoib_hdr *ipoib_hdr; 00483 struct ipoib_mac ll_src; 00484 struct ipoib_peer *src; 00485 00486 if ( rc != 0 ) { 00487 netdev_rx_err ( netdev, iobuf, rc ); 00488 return; 00489 } 00490 00491 /* Sanity check */ 00492 if ( iob_len ( iobuf ) < sizeof ( struct ipoib_hdr ) ) { 00493 DBGC ( ipoib, "IPoIB %p received packet too short to " 00494 "contain IPoIB header\n", ipoib ); 00495 DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) ); 00496 netdev_rx_err ( netdev, iobuf, -EIO ); 00497 return; 00498 } 00499 ipoib_hdr = iobuf->data; 00500 00501 /* Parse source address */ 00502 if ( av->gid_present ) { 00503 ll_src.flags__qpn = htonl ( av->qpn ); 00504 memcpy ( &ll_src.gid, &av->gid, sizeof ( ll_src.gid ) ); 00505 src = ipoib_cache_peer ( &ll_src ); 00506 ipoib_hdr->u.peer.src = src->key; 00507 } 00508 00509 /* Hand off to network layer */ 00510 netdev_rx ( netdev, iobuf ); 00511 }
| static void ipoib_poll | ( | struct net_device * | netdev | ) | [static] |
Poll IPoIB network device.
| netdev | Network device |
Definition at line 524 of file ipoib.c.
References ib_poll_eq(), ipoib_device::ibdev, and net_device::priv.
00524 { 00525 struct ipoib_device *ipoib = netdev->priv; 00526 struct ib_device *ibdev = ipoib->ibdev; 00527 00528 ib_poll_eq ( ibdev ); 00529 }
| static void ipoib_irq | ( | struct net_device *netdev | __unused, | |
| int enable | __unused | |||
| ) | [static] |
| void ipoib_join_complete | ( | struct ib_device *ibdev | __unused, | |
| struct ib_queue_pair *qp | __unused, | |||
| struct ib_mc_membership * | membership, | |||
| int | rc, | |||
| union ib_mad *mad | __unused | |||
| ) |
Handle IPv4 broadcast multicast group join completion.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| membership | Multicast group membership | |
| rc | Status code | |
| mad | Response MAD (or NULL on error) |
Definition at line 551 of file ipoib.c.
References ipoib_device::broadcast_membership, container_of, ipoib_device::netdev, and netdev_link_err().
Referenced by ipoib_join_broadcast_group().
00554 { 00555 struct ipoib_device *ipoib = container_of ( membership, 00556 struct ipoib_device, broadcast_membership ); 00557 00558 /* Record join status as link status */ 00559 netdev_link_err ( ipoib->netdev, rc ); 00560 }
| static int ipoib_join_broadcast_group | ( | struct ipoib_device * | ipoib | ) | [static] |
Join IPv4 broadcast multicast group.
| ipoib | IPoIB device |
| rc | Return status code |
Definition at line 568 of file ipoib.c.
References ipoib_device::broadcast, ipoib_device::broadcast_joined, ipoib_device::broadcast_membership, DBGC, ipoib_mac::gid, ib_mcast_join(), ipoib_device::ibdev, ipoib_join_complete(), ipoib_device::qp, and strerror().
Referenced by ipoib_link_state_changed().
00568 { 00569 int rc; 00570 00571 if ( ( rc = ib_mcast_join ( ipoib->ibdev, ipoib->qp, 00572 &ipoib->broadcast_membership, 00573 &ipoib->broadcast.gid, 00574 ipoib_join_complete ) ) != 0 ) { 00575 DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n", 00576 ipoib, strerror ( rc ) ); 00577 return rc; 00578 } 00579 ipoib->broadcast_joined = 1; 00580 00581 return 0; 00582 }
| static void ipoib_leave_broadcast_group | ( | struct ipoib_device * | ipoib | ) | [static] |
Leave IPv4 broadcast multicast group.
| ipoib | IPoIB device |
Definition at line 589 of file ipoib.c.
References ipoib_device::broadcast_joined, ipoib_device::broadcast_membership, ib_mcast_leave(), ipoib_device::ibdev, and ipoib_device::qp.
Referenced by ipoib_close(), and ipoib_link_state_changed().
00589 { 00590 00591 if ( ipoib->broadcast_joined ) { 00592 ib_mcast_leave ( ipoib->ibdev, ipoib->qp, 00593 &ipoib->broadcast_membership ); 00594 ipoib->broadcast_joined = 0; 00595 } 00596 }
| static int ipoib_open | ( | struct net_device * | netdev | ) | [static] |
Open IPoIB network device.
| netdev | Network device |
| rc | Return status code |
Definition at line 604 of file ipoib.c.
References ipoib_device::cq, DBGC, ENOMEM, ipoib_mac::flags__qpn, htonl, ib_close(), ib_create_cq(), ib_create_qp(), ib_destroy_cq(), ib_destroy_qp(), ib_open(), ib_qp_set_ownerdata(), IB_QPT_UD, ib_refill_recv(), ipoib_device::ibdev, ipoib_link_state_changed(), IPOIB_NUM_CQES, IPOIB_NUM_RECV_WQES, IPOIB_NUM_SEND_WQES, net_device::ll_addr, net_device::priv, ipoib_device::qp, ib_queue_pair::qpn, and strerror().
00604 { 00605 struct ipoib_device *ipoib = netdev->priv; 00606 struct ib_device *ibdev = ipoib->ibdev; 00607 struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr ); 00608 int rc; 00609 00610 /* Open IB device */ 00611 if ( ( rc = ib_open ( ibdev ) ) != 0 ) { 00612 DBGC ( ipoib, "IPoIB %p could not open device: %s\n", 00613 ipoib, strerror ( rc ) ); 00614 goto err_ib_open; 00615 } 00616 00617 /* Allocate completion queue */ 00618 ipoib->cq = ib_create_cq ( ibdev, IPOIB_NUM_CQES, &ipoib_cq_op ); 00619 if ( ! ipoib->cq ) { 00620 DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n", 00621 ipoib ); 00622 rc = -ENOMEM; 00623 goto err_create_cq; 00624 } 00625 00626 /* Allocate queue pair */ 00627 ipoib->qp = ib_create_qp ( ibdev, IB_QPT_UD, 00628 IPOIB_NUM_SEND_WQES, ipoib->cq, 00629 IPOIB_NUM_RECV_WQES, ipoib->cq ); 00630 if ( ! ipoib->qp ) { 00631 DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n", 00632 ipoib ); 00633 rc = -ENOMEM; 00634 goto err_create_qp; 00635 } 00636 ib_qp_set_ownerdata ( ipoib->qp, ipoib ); 00637 00638 /* Update MAC address with QPN */ 00639 mac->flags__qpn = htonl ( ipoib->qp->qpn ); 00640 00641 /* Fill receive rings */ 00642 ib_refill_recv ( ibdev, ipoib->qp ); 00643 00644 /* Fake a link status change to join the broadcast group */ 00645 ipoib_link_state_changed ( ibdev ); 00646 00647 return 0; 00648 00649 ib_destroy_qp ( ibdev, ipoib->qp ); 00650 err_create_qp: 00651 ib_destroy_cq ( ibdev, ipoib->cq ); 00652 err_create_cq: 00653 ib_close ( ibdev ); 00654 err_ib_open: 00655 return rc; 00656 }
| static void ipoib_close | ( | struct net_device * | netdev | ) | [static] |
Close IPoIB network device.
| netdev | Network device |
Definition at line 663 of file ipoib.c.
References ipoib_device::cq, ipoib_mac::flags__qpn, ib_close(), ib_destroy_cq(), ib_destroy_qp(), ipoib_device::ibdev, ipoib_leave_broadcast_group(), net_device::ll_addr, net_device::priv, and ipoib_device::qp.
00663 { 00664 struct ipoib_device *ipoib = netdev->priv; 00665 struct ib_device *ibdev = ipoib->ibdev; 00666 struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr ); 00667 00668 /* Leave broadcast group */ 00669 ipoib_leave_broadcast_group ( ipoib ); 00670 00671 /* Remove QPN from MAC address */ 00672 mac->flags__qpn = 0; 00673 00674 /* Tear down the queues */ 00675 ib_destroy_qp ( ibdev, ipoib->qp ); 00676 ib_destroy_cq ( ibdev, ipoib->cq ); 00677 00678 /* Close IB device */ 00679 ib_close ( ibdev ); 00680 }
| void ipoib_link_state_changed | ( | struct ib_device * | ibdev | ) |
Handle link status change.
| ibdev | Infiniband device |
Definition at line 696 of file ipoib.c.
References ipoib_device::broadcast, DBGC, EINPROGRESS_JOINING, ib_device::gid, ipoib_mac::gid, ib_gid::half, htons, ib_get_ownerdata(), ib_link_ok(), ib_link_rc(), IB_PKEY_FULL, ipoib_join_broadcast_group(), ipoib_leave_broadcast_group(), net_device::ll_addr, memcpy, netdev, netdev_link_err(), ib_device::pkey, net_device::priv, strerror(), ib_gid::u, and ib_gid::words.
Referenced by ib_link_state_changed(), and ipoib_open().
00696 { 00697 struct net_device *netdev = ib_get_ownerdata ( ibdev ); 00698 struct ipoib_device *ipoib = netdev->priv; 00699 struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr ); 00700 int rc; 00701 00702 /* Leave existing broadcast group */ 00703 ipoib_leave_broadcast_group ( ipoib ); 00704 00705 /* Update MAC address based on potentially-new GID prefix */ 00706 memcpy ( &mac->gid.u.half[0], &ibdev->gid.u.half[0], 00707 sizeof ( mac->gid.u.half[0] ) ); 00708 00709 /* Update broadcast GID based on potentially-new partition key */ 00710 ipoib->broadcast.gid.u.words[2] = 00711 htons ( ibdev->pkey | IB_PKEY_FULL ); 00712 00713 /* Set net device link state to reflect Infiniband link state */ 00714 rc = ib_link_rc ( ibdev ); 00715 netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) ); 00716 00717 /* Join new broadcast group */ 00718 if ( ib_link_ok ( ibdev ) && 00719 ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) { 00720 DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: " 00721 "%s\n", ipoib, strerror ( rc ) ); 00722 netdev_link_err ( netdev, rc ); 00723 return; 00724 } 00725 }
| int ipoib_probe | ( | struct ib_device * | ibdev | ) |
Probe IPoIB device.
| ibdev | Infiniband device |
| rc | Return status code |
Definition at line 733 of file ipoib.c.
References alloc_ipoibdev(), ipoib_device::broadcast, ib_device::dev, net_device::dev, ENOMEM, ib_device::gid, ib_gid::half, net_device::hw_addr, ib_set_ownerdata(), ipoib_device::ibdev, net_device::ll_broadcast, memcpy, memset(), ipoib_device::netdev, netdev, netdev_init(), netdev_nullify(), netdev_put(), net_device::priv, register_netdev(), and ib_gid::u.
Referenced by register_ibdev().
00733 { 00734 struct net_device *netdev; 00735 struct ipoib_device *ipoib; 00736 int rc; 00737 00738 /* Allocate network device */ 00739 netdev = alloc_ipoibdev ( sizeof ( *ipoib ) ); 00740 if ( ! netdev ) 00741 return -ENOMEM; 00742 netdev_init ( netdev, &ipoib_operations ); 00743 ipoib = netdev->priv; 00744 ib_set_ownerdata ( ibdev, netdev ); 00745 netdev->dev = ibdev->dev; 00746 memset ( ipoib, 0, sizeof ( *ipoib ) ); 00747 ipoib->netdev = netdev; 00748 ipoib->ibdev = ibdev; 00749 00750 /* Extract hardware address */ 00751 memcpy ( netdev->hw_addr, &ibdev->gid.u.half[1], 00752 sizeof ( ibdev->gid.u.half[1] ) ); 00753 00754 /* Set default broadcast address */ 00755 memcpy ( &ipoib->broadcast, &ipoib_broadcast, 00756 sizeof ( ipoib->broadcast ) ); 00757 netdev->ll_broadcast = ( ( uint8_t * ) &ipoib->broadcast ); 00758 00759 /* Register network device */ 00760 if ( ( rc = register_netdev ( netdev ) ) != 0 ) 00761 goto err_register_netdev; 00762 00763 return 0; 00764 00765 err_register_netdev: 00766 netdev_nullify ( netdev ); 00767 netdev_put ( netdev ); 00768 return rc; 00769 }
| void ipoib_remove | ( | struct ib_device * | ibdev | ) |
Remove IPoIB device.
| ibdev | Infiniband device |
Definition at line 776 of file ipoib.c.
References ib_get_ownerdata(), netdev, netdev_nullify(), netdev_put(), and unregister_netdev().
Referenced by unregister_ibdev().
00776 { 00777 struct net_device *netdev = ib_get_ownerdata ( ibdev ); 00778 00779 unregister_netdev ( netdev ); 00780 netdev_nullify ( netdev ); 00781 netdev_put ( netdev ); 00782 }
struct ipoib_mac ipoib_broadcast [static] |
Initial value:
{
.flags__qpn = htonl ( IB_QPN_BROADCAST ),
.gid.u.bytes = { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff },
}
| struct errortab ipoib_errors [] __errortab |
struct ipoib_peer ipoib_peer_cache[IPOIB_NUM_CACHED_PEERS] [static] |
IPoIB peer address cache.
Definition at line 118 of file ipoib.c.
Referenced by ipoib_cache_peer(), and ipoib_lookup_peer_by_key().
unsigned int ipoib_peer_cache_idx = 1 [static] |
Oldest IPoIB peer cache entry index.
Definition at line 121 of file ipoib.c.
Referenced by ipoib_cache_peer().
struct ipoib_eth_addr_handler ipoib_eth_addr_handlers[] [static] |
Initial value:
{
{ 0x02, 0xc9, ipoib_mlx_eth_addr },
}
| struct ll_protocol ipoib_protocol __ll_protocol |
Initial value:
{
.name = "IPoIB",
.ll_proto = htons ( ARPHRD_INFINIBAND ),
.hw_addr_len = sizeof ( struct ib_gid_half ),
.ll_addr_len = IPOIB_ALEN,
.ll_header_len = IPOIB_HLEN,
.push = ipoib_push,
.pull = ipoib_pull,
.init_addr = ipoib_init_addr,
.ntoa = ipoib_ntoa,
.mc_hash = ipoib_mc_hash,
.eth_addr = ipoib_eth_addr,
}
struct ib_completion_queue_operations ipoib_cq_op [static] |
Initial value:
{
.complete_send = ipoib_complete_send,
.complete_recv = ipoib_complete_recv,
}
struct net_device_operations ipoib_operations [static] |
Initial value:
{
.open = ipoib_open,
.close = ipoib_close,
.transmit = ipoib_transmit,
.poll = ipoib_poll,
.irq = ipoib_irq,
}
1.5.7.1