Browse Source

[hermon] Work around hardware stripping of VLAN tags

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
f14a5045d7
2 changed files with 21 additions and 3 deletions
  1. 17
    3
      src/drivers/infiniband/hermon.c
  2. 4
    0
      src/include/ipxe/infiniband.h

+ 17
- 3
src/drivers/infiniband/hermon.c View File

39
 #include <ipxe/if_ether.h>
39
 #include <ipxe/if_ether.h>
40
 #include <ipxe/ethernet.h>
40
 #include <ipxe/ethernet.h>
41
 #include <ipxe/fcoe.h>
41
 #include <ipxe/fcoe.h>
42
+#include <ipxe/vlan.h>
42
 #include "hermon.h"
43
 #include "hermon.h"
43
 
44
 
44
 /**
45
 /**
1648
 		len = MLX_GET ( &cqe->normal, byte_cnt );
1649
 		len = MLX_GET ( &cqe->normal, byte_cnt );
1649
 		assert ( len <= iob_tailroom ( iobuf ) );
1650
 		assert ( len <= iob_tailroom ( iobuf ) );
1650
 		iob_put ( iobuf, len );
1651
 		iob_put ( iobuf, len );
1652
+		memset ( &recv_av, 0, sizeof ( recv_av ) );
1651
 		switch ( qp->type ) {
1653
 		switch ( qp->type ) {
1652
 		case IB_QPT_SMI:
1654
 		case IB_QPT_SMI:
1653
 		case IB_QPT_GSI:
1655
 		case IB_QPT_GSI:
1657
 			iob_pull ( iobuf, sizeof ( *grh ) );
1659
 			iob_pull ( iobuf, sizeof ( *grh ) );
1658
 			/* Construct address vector */
1660
 			/* Construct address vector */
1659
 			av = &recv_av;
1661
 			av = &recv_av;
1660
-			memset ( av, 0, sizeof ( *av ) );
1661
 			av->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
1662
 			av->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
1662
 			av->lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
1663
 			av->lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
1663
 			av->sl = MLX_GET ( &cqe->normal, sl );
1664
 			av->sl = MLX_GET ( &cqe->normal, sl );
1668
 			av = &qp->av;
1669
 			av = &qp->av;
1669
 			break;
1670
 			break;
1670
 		case IB_QPT_ETH:
1671
 		case IB_QPT_ETH:
1671
-			av = NULL;
1672
+			/* Construct address vector */
1673
+			av = &recv_av;
1674
+			av->vlan_present = MLX_GET ( &cqe->normal, vlan );
1675
+			av->vlan = MLX_GET ( &cqe->normal, vid );
1672
 			break;
1676
 			break;
1673
 		default:
1677
 		default:
1674
 			assert ( 0 );
1678
 			assert ( 0 );
2275
  */
2279
  */
2276
 static void hermon_eth_complete_recv ( struct ib_device *ibdev __unused,
2280
 static void hermon_eth_complete_recv ( struct ib_device *ibdev __unused,
2277
 				       struct ib_queue_pair *qp,
2281
 				       struct ib_queue_pair *qp,
2278
-				       struct ib_address_vector *av __unused,
2282
+				       struct ib_address_vector *av,
2279
 				       struct io_buffer *iobuf, int rc ) {
2283
 				       struct io_buffer *iobuf, int rc ) {
2280
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
2284
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
2285
+	struct net_device *vlan;
2286
+
2287
+	/* Find VLAN device, if applicable */
2288
+	if ( av->vlan_present ) {
2289
+		if ( ( vlan = vlan_find ( netdev, av->vlan ) ) != NULL ) {
2290
+			netdev = vlan;
2291
+		} else if ( rc == 0 ) {
2292
+			rc = -ENODEV;
2293
+		}
2294
+	}
2281
 
2295
 
2282
 	/* Hand off to network layer */
2296
 	/* Hand off to network layer */
2283
 	if ( rc == 0 ) {
2297
 	if ( rc == 0 ) {

+ 4
- 0
src/include/ipxe/infiniband.h View File

89
 	unsigned int gid_present;
89
 	unsigned int gid_present;
90
 	/** GID, if present */
90
 	/** GID, if present */
91
 	union ib_gid gid;
91
 	union ib_gid gid;
92
+	/** VLAN is present */
93
+	unsigned int vlan_present;
94
+	/** VLAN, if present */
95
+	unsigned int vlan;
92
 };
96
 };
93
 
97
 
94
 /** An Infiniband Work Queue */
98
 /** An Infiniband Work Queue */

Loading…
Cancel
Save