diff options
author | Michael Brown | 2007-09-12 23:17:43 +0200 |
---|---|---|
committer | Michael Brown | 2007-09-12 23:17:43 +0200 |
commit | 7b6d11e7136cee21cc9a76614174abac999f6173 (patch) | |
tree | f87381e9857a46b5a96b32d63695fa5b71192fba /src/net/infiniband.c | |
parent | Merge branch 'master' into 3leaf-rewrite (diff) | |
download | ipxe-7b6d11e7136cee21cc9a76614174abac999f6173.tar.gz ipxe-7b6d11e7136cee21cc9a76614174abac999f6173.tar.xz ipxe-7b6d11e7136cee21cc9a76614174abac999f6173.zip |
Started IB driver rewrite
Diffstat (limited to 'src/net/infiniband.c')
-rw-r--r-- | src/net/infiniband.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/net/infiniband.c b/src/net/infiniband.c new file mode 100644 index 00000000..bcfac292 --- /dev/null +++ b/src/net/infiniband.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <byteswap.h> +#include <errno.h> +#include <assert.h> +#include <gpxe/if_arp.h> +#include <gpxe/netdevice.h> +#include <gpxe/iobuf.h> +#include <gpxe/infiniband.h> + +/** @file + * + * Infiniband protocol + * + */ + +/** Infiniband broadcast MAC address */ +static uint8_t ib_broadcast[IB_ALEN] = { 0xff, }; + +/** + * Transmit Infiniband packet + * + * @v iobuf I/O buffer + * @v netdev Network device + * @v net_protocol Network-layer protocol + * @v ll_dest Link-layer destination address + * + * Prepends the Infiniband link-layer header and transmits the packet. + */ +static int ib_tx ( struct io_buffer *iobuf, struct net_device *netdev, + struct net_protocol *net_protocol, const void *ll_dest ) { + struct ibhdr *ibhdr = iob_push ( iobuf, sizeof ( *ibhdr ) ); + + + /* Build Infiniband header */ + memcpy ( ibhdr->peer, ll_dest, IB_ALEN ); + ibhdr->proto = net_protocol->net_proto; + ibhdr->reserved = 0; + + /* Hand off to network device */ + return netdev_tx ( netdev, iobuf ); +} + +/** + * Process received Infiniband packet + * + * @v iobuf I/O buffer + * @v netdev Network device + * + * Strips off the Infiniband link-layer header and passes up to the + * network-layer protocol. + */ +static int ib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) { + struct ibhdr *ibhdr = iobuf->data; + + /* Sanity check */ + if ( iob_len ( iobuf ) < sizeof ( *ibhdr ) ) { + DBG ( "Infiniband packet too short (%d bytes)\n", + iob_len ( iobuf ) ); + free_iob ( iobuf ); + return -EINVAL; + } + + /* Strip off Infiniband header */ + iob_pull ( iobuf, sizeof ( *ibhdr ) ); + + /* Hand off to network-layer protocol */ + return net_rx ( iobuf, netdev, ibhdr->proto, ibhdr->peer ); +} + +/** + * Transcribe Infiniband address + * + * @v ll_addr Link-layer address + * @ret string Link-layer address in human-readable format + */ +const char * ib_ntoa ( const void *ll_addr ) { + static char buf[61]; + const uint8_t *ib_addr = ll_addr; + unsigned int i; + char *p = buf; + + for ( i = 0 ; i < IB_ALEN ; i++ ) { + p += sprintf ( p, ":%02x", ib_addr[i] ); + } + return ( buf + 1 ); +} + +/** Infiniband protocol */ +struct ll_protocol infiniband_protocol __ll_protocol = { + .name = "Infiniband", + .ll_proto = htons ( ARPHRD_INFINIBAND ), + .ll_addr_len = IB_ALEN, + .ll_header_len = IB_HLEN, + .ll_broadcast = ib_broadcast, + .tx = ib_tx, + .rx = ib_rx, + .ntoa = ib_ntoa, +}; |