Pārlūkot izejas kodu

[rndis] Clear receive filter when closing the device

On Windows Server 2012 R2, closing and reopening the device will
sometimes result in a non-functional RX datapath.  The root cause is
unknown.  Clearing the receive filter before closing the device seems
to fix the problem.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 gadus atpakaļ
vecāks
revīzija
67291465ea
1 mainītis faili ar 30 papildinājumiem un 11 dzēšanām
  1. 30
    11
      src/net/rndis.c

+ 30
- 11
src/net/rndis.c Parādīt failu

@@ -828,6 +828,28 @@ void rndis_rx ( struct rndis_device *rndis, struct io_buffer *iobuf ) {
828 828
 	netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
829 829
 }
830 830
 
831
+/**
832
+ * Set receive filter
833
+ *
834
+ * @v rndis		RNDIS device
835
+ * @v filter		Receive filter
836
+ * @ret rc		Return status code
837
+ */
838
+static int rndis_filter ( struct rndis_device *rndis, unsigned int filter ) {
839
+	uint32_t value = cpu_to_le32 ( filter );
840
+	int rc;
841
+
842
+	/* Set receive filter */
843
+	if ( ( rc = rndis_oid ( rndis, RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
844
+				&value, sizeof ( value ) ) ) != 0 ) {
845
+		DBGC ( rndis, "RNDIS %s could not set receive filter to %#08x: "
846
+		       "%s\n", rndis->name, filter, strerror ( rc ) );
847
+		return rc;
848
+	}
849
+
850
+	return 0;
851
+}
852
+
831 853
 /**
832 854
  * Open network device
833 855
  *
@@ -836,7 +858,6 @@ void rndis_rx ( struct rndis_device *rndis, struct io_buffer *iobuf ) {
836 858
  */
837 859
 static int rndis_open ( struct net_device *netdev ) {
838 860
 	struct rndis_device *rndis = netdev->priv;
839
-	uint32_t filter;
840 861
 	int rc;
841 862
 
842 863
 	/* Open RNDIS device */
@@ -851,17 +872,12 @@ static int rndis_open ( struct net_device *netdev ) {
851 872
 		goto err_initialise;
852 873
 
853 874
 	/* Set receive filter */
854
-	filter = cpu_to_le32 ( RNDIS_FILTER_UNICAST |
855
-			       RNDIS_FILTER_MULTICAST |
856
-			       RNDIS_FILTER_ALL_MULTICAST |
857
-			       RNDIS_FILTER_BROADCAST |
858
-			       RNDIS_FILTER_PROMISCUOUS );
859
-	if ( ( rc = rndis_oid ( rndis, RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
860
-				&filter, sizeof ( filter ) ) ) != 0 ) {
861
-		DBGC ( rndis, "RNDIS %s could not set receive filter: %s\n",
862
-		       rndis->name, strerror ( rc ) );
875
+	if ( ( rc = rndis_filter ( rndis, ( RNDIS_FILTER_UNICAST |
876
+					    RNDIS_FILTER_MULTICAST |
877
+					    RNDIS_FILTER_ALL_MULTICAST |
878
+					    RNDIS_FILTER_BROADCAST |
879
+					    RNDIS_FILTER_PROMISCUOUS ) ) ) != 0)
863 880
 		goto err_set_filter;
864
-	}
865 881
 
866 882
 	/* Update link status */
867 883
 	if ( ( rc = rndis_oid ( rndis, RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
@@ -887,6 +903,9 @@ static int rndis_open ( struct net_device *netdev ) {
887 903
 static void rndis_close ( struct net_device *netdev ) {
888 904
 	struct rndis_device *rndis = netdev->priv;
889 905
 
906
+	/* Clear receive filter */
907
+	rndis_filter ( rndis, 0 );
908
+
890 909
 	/* Halt RNDIS device */
891 910
 	rndis_halt ( rndis );
892 911
 

Notiek ielāde…
Atcelt
Saglabāt