mirror of
https://github.com/ipxe/ipxe
synced 2025-12-29 11:03:15 +03:00
[hermon] Work around hardware stripping of VLAN tags
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -39,6 +39,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
|||||||
#include <ipxe/if_ether.h>
|
#include <ipxe/if_ether.h>
|
||||||
#include <ipxe/ethernet.h>
|
#include <ipxe/ethernet.h>
|
||||||
#include <ipxe/fcoe.h>
|
#include <ipxe/fcoe.h>
|
||||||
|
#include <ipxe/vlan.h>
|
||||||
#include "hermon.h"
|
#include "hermon.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1648,6 +1649,7 @@ static int hermon_complete ( struct ib_device *ibdev,
|
|||||||
len = MLX_GET ( &cqe->normal, byte_cnt );
|
len = MLX_GET ( &cqe->normal, byte_cnt );
|
||||||
assert ( len <= iob_tailroom ( iobuf ) );
|
assert ( len <= iob_tailroom ( iobuf ) );
|
||||||
iob_put ( iobuf, len );
|
iob_put ( iobuf, len );
|
||||||
|
memset ( &recv_av, 0, sizeof ( recv_av ) );
|
||||||
switch ( qp->type ) {
|
switch ( qp->type ) {
|
||||||
case IB_QPT_SMI:
|
case IB_QPT_SMI:
|
||||||
case IB_QPT_GSI:
|
case IB_QPT_GSI:
|
||||||
@@ -1657,7 +1659,6 @@ static int hermon_complete ( struct ib_device *ibdev,
|
|||||||
iob_pull ( iobuf, sizeof ( *grh ) );
|
iob_pull ( iobuf, sizeof ( *grh ) );
|
||||||
/* Construct address vector */
|
/* Construct address vector */
|
||||||
av = &recv_av;
|
av = &recv_av;
|
||||||
memset ( av, 0, sizeof ( *av ) );
|
|
||||||
av->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
|
av->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
|
||||||
av->lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
|
av->lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
|
||||||
av->sl = MLX_GET ( &cqe->normal, sl );
|
av->sl = MLX_GET ( &cqe->normal, sl );
|
||||||
@@ -1668,7 +1669,10 @@ static int hermon_complete ( struct ib_device *ibdev,
|
|||||||
av = &qp->av;
|
av = &qp->av;
|
||||||
break;
|
break;
|
||||||
case IB_QPT_ETH:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
assert ( 0 );
|
assert ( 0 );
|
||||||
@@ -2275,9 +2279,19 @@ static void hermon_eth_complete_send ( struct ib_device *ibdev __unused,
|
|||||||
*/
|
*/
|
||||||
static void hermon_eth_complete_recv ( struct ib_device *ibdev __unused,
|
static void hermon_eth_complete_recv ( struct ib_device *ibdev __unused,
|
||||||
struct ib_queue_pair *qp,
|
struct ib_queue_pair *qp,
|
||||||
struct ib_address_vector *av __unused,
|
struct ib_address_vector *av,
|
||||||
struct io_buffer *iobuf, int rc ) {
|
struct io_buffer *iobuf, int rc ) {
|
||||||
struct net_device *netdev = ib_qp_get_ownerdata ( qp );
|
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 */
|
/* Hand off to network layer */
|
||||||
if ( rc == 0 ) {
|
if ( rc == 0 ) {
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ struct ib_address_vector {
|
|||||||
unsigned int gid_present;
|
unsigned int gid_present;
|
||||||
/** GID, if present */
|
/** GID, if present */
|
||||||
union ib_gid gid;
|
union ib_gid gid;
|
||||||
|
/** VLAN is present */
|
||||||
|
unsigned int vlan_present;
|
||||||
|
/** VLAN, if present */
|
||||||
|
unsigned int vlan;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An Infiniband Work Queue */
|
/** An Infiniband Work Queue */
|
||||||
|
|||||||
Reference in New Issue
Block a user