Просмотр исходного кода

[hermon] Work around hardware stripping of VLAN tags

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 лет назад
Родитель
Сommit
f14a5045d7
2 измененных файлов: 21 добавлений и 3 удалений
  1. 17
    3
      src/drivers/infiniband/hermon.c
  2. 4
    0
      src/include/ipxe/infiniband.h

+ 17
- 3
src/drivers/infiniband/hermon.c Просмотреть файл

@@ -39,6 +39,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
39 39
 #include <ipxe/if_ether.h>
40 40
 #include <ipxe/ethernet.h>
41 41
 #include <ipxe/fcoe.h>
42
+#include <ipxe/vlan.h>
42 43
 #include "hermon.h"
43 44
 
44 45
 /**
@@ -1648,6 +1649,7 @@ static int hermon_complete ( struct ib_device *ibdev,
1648 1649
 		len = MLX_GET ( &cqe->normal, byte_cnt );
1649 1650
 		assert ( len <= iob_tailroom ( iobuf ) );
1650 1651
 		iob_put ( iobuf, len );
1652
+		memset ( &recv_av, 0, sizeof ( recv_av ) );
1651 1653
 		switch ( qp->type ) {
1652 1654
 		case IB_QPT_SMI:
1653 1655
 		case IB_QPT_GSI:
@@ -1657,7 +1659,6 @@ static int hermon_complete ( struct ib_device *ibdev,
1657 1659
 			iob_pull ( iobuf, sizeof ( *grh ) );
1658 1660
 			/* Construct address vector */
1659 1661
 			av = &recv_av;
1660
-			memset ( av, 0, sizeof ( *av ) );
1661 1662
 			av->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
1662 1663
 			av->lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
1663 1664
 			av->sl = MLX_GET ( &cqe->normal, sl );
@@ -1668,7 +1669,10 @@ static int hermon_complete ( struct ib_device *ibdev,
1668 1669
 			av = &qp->av;
1669 1670
 			break;
1670 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 1676
 			break;
1673 1677
 		default:
1674 1678
 			assert ( 0 );
@@ -2275,9 +2279,19 @@ static void hermon_eth_complete_send ( struct ib_device *ibdev __unused,
2275 2279
  */
2276 2280
 static void hermon_eth_complete_recv ( struct ib_device *ibdev __unused,
2277 2281
 				       struct ib_queue_pair *qp,
2278
-				       struct ib_address_vector *av __unused,
2282
+				       struct ib_address_vector *av,
2279 2283
 				       struct io_buffer *iobuf, int rc ) {
2280 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 2296
 	/* Hand off to network layer */
2283 2297
 	if ( rc == 0 ) {

+ 4
- 0
src/include/ipxe/infiniband.h Просмотреть файл

@@ -89,6 +89,10 @@ struct ib_address_vector {
89 89
 	unsigned int gid_present;
90 90
 	/** GID, if present */
91 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 98
 /** An Infiniband Work Queue */

Загрузка…
Отмена
Сохранить