#include <ipxe/if_ether.h>
#include <ipxe/ethernet.h>
#include <ipxe/fcoe.h>
+#include <ipxe/vlan.h>
#include "hermon.h"
/**
len = MLX_GET ( &cqe->normal, byte_cnt );
assert ( len <= iob_tailroom ( iobuf ) );
iob_put ( iobuf, len );
+ memset ( &recv_av, 0, sizeof ( recv_av ) );
switch ( qp->type ) {
case IB_QPT_SMI:
case IB_QPT_GSI:
iob_pull ( iobuf, sizeof ( *grh ) );
/* Construct address vector */
av = &recv_av;
- memset ( av, 0, sizeof ( *av ) );
av->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
av->lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
av->sl = MLX_GET ( &cqe->normal, sl );
av = &qp->av;
break;
case IB_QPT_ETH:
- av = NULL;
+ /* Construct address vector */
+ av = &recv_av;
+ av->vlan_present = MLX_GET ( &cqe->normal, vlan );
+ av->vlan = MLX_GET ( &cqe->normal, vid );
break;
default:
assert ( 0 );
*/
static void hermon_eth_complete_recv ( struct ib_device *ibdev __unused,
struct ib_queue_pair *qp,
- struct ib_address_vector *av __unused,
+ struct ib_address_vector *av,
struct io_buffer *iobuf, int rc ) {
struct net_device *netdev = ib_qp_get_ownerdata ( qp );
+ struct net_device *vlan;
+
+ /* Find VLAN device, if applicable */
+ if ( av->vlan_present ) {
+ if ( ( vlan = vlan_find ( netdev, av->vlan ) ) != NULL ) {
+ netdev = vlan;
+ } else if ( rc == 0 ) {
+ rc = -ENODEV;
+ }
+ }
/* Hand off to network layer */
if ( rc == 0 ) {