mirror of https://github.com/ipxe/ipxe.git
[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>pull/33/head
parent
cd68d93b6e
commit
67291465ea
|
@ -828,6 +828,28 @@ void rndis_rx ( struct rndis_device *rndis, struct io_buffer *iobuf ) {
|
|||
netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set receive filter
|
||||
*
|
||||
* @v rndis RNDIS device
|
||||
* @v filter Receive filter
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int rndis_filter ( struct rndis_device *rndis, unsigned int filter ) {
|
||||
uint32_t value = cpu_to_le32 ( filter );
|
||||
int rc;
|
||||
|
||||
/* Set receive filter */
|
||||
if ( ( rc = rndis_oid ( rndis, RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&value, sizeof ( value ) ) ) != 0 ) {
|
||||
DBGC ( rndis, "RNDIS %s could not set receive filter to %#08x: "
|
||||
"%s\n", rndis->name, filter, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open network device
|
||||
*
|
||||
|
@ -836,7 +858,6 @@ void rndis_rx ( struct rndis_device *rndis, struct io_buffer *iobuf ) {
|
|||
*/
|
||||
static int rndis_open ( struct net_device *netdev ) {
|
||||
struct rndis_device *rndis = netdev->priv;
|
||||
uint32_t filter;
|
||||
int rc;
|
||||
|
||||
/* Open RNDIS device */
|
||||
|
@ -851,17 +872,12 @@ static int rndis_open ( struct net_device *netdev ) {
|
|||
goto err_initialise;
|
||||
|
||||
/* Set receive filter */
|
||||
filter = cpu_to_le32 ( RNDIS_FILTER_UNICAST |
|
||||
RNDIS_FILTER_MULTICAST |
|
||||
RNDIS_FILTER_ALL_MULTICAST |
|
||||
RNDIS_FILTER_BROADCAST |
|
||||
RNDIS_FILTER_PROMISCUOUS );
|
||||
if ( ( rc = rndis_oid ( rndis, RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&filter, sizeof ( filter ) ) ) != 0 ) {
|
||||
DBGC ( rndis, "RNDIS %s could not set receive filter: %s\n",
|
||||
rndis->name, strerror ( rc ) );
|
||||
if ( ( rc = rndis_filter ( rndis, ( RNDIS_FILTER_UNICAST |
|
||||
RNDIS_FILTER_MULTICAST |
|
||||
RNDIS_FILTER_ALL_MULTICAST |
|
||||
RNDIS_FILTER_BROADCAST |
|
||||
RNDIS_FILTER_PROMISCUOUS ) ) ) != 0)
|
||||
goto err_set_filter;
|
||||
}
|
||||
|
||||
/* Update link status */
|
||||
if ( ( rc = rndis_oid ( rndis, RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
|
||||
|
@ -887,6 +903,9 @@ static int rndis_open ( struct net_device *netdev ) {
|
|||
static void rndis_close ( struct net_device *netdev ) {
|
||||
struct rndis_device *rndis = netdev->priv;
|
||||
|
||||
/* Clear receive filter */
|
||||
rndis_filter ( rndis, 0 );
|
||||
|
||||
/* Halt RNDIS device */
|
||||
rndis_halt ( rndis );
|
||||
|
||||
|
|
Loading…
Reference in New Issue