diff mbox

[v2] rtl8187: Enable monitor mode to fix multicast reception

Message ID 20170219235919.GA15763@tisys.org (mailing list archive)
State Accepted
Commit 3beb27028c446dce74a1690ea3ef2dfae7503e74
Delegated to: Kalle Valo
Headers show

Commit Message

Nils Holland Feb. 19, 2017, 11:59 p.m. UTC
The rtl8187 cards don't seem to receive multicast frames, which,
among other things, makes them fail to receive RAs in IPv6 networks.
The cause seems to be that the RTL818X_RX_CONF_MULTICAST flag doesn't
have the desired effect.

Fix the issue by setting RTL818X_RX_CONF_MONITOR instead, which puts the
card into monitor mode and resolves the problem so that multicast frames
are sucessfully passed to the kernel.

The existence of the problem and the effectiveness of the solution has
originally been confirmed on an 8187B based card with the USB id of
0bda:8197. Subsequent testing by Larry Finger on an 8187L based card,
which follows the second (8187, i.e. "non-b") code path in the driver,
has confirmed that the fix does not cause any noticeable regresssions
there either.

Signed-off-by: Nils Holland <nholland@tisys.org>
---
 drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

Comments

Larry Finger Feb. 20, 2017, 1:17 a.m. UTC | #1
On 02/19/2017 05:59 PM, Nils Holland wrote:
> The rtl8187 cards don't seem to receive multicast frames, which,
> among other things, makes them fail to receive RAs in IPv6 networks.
> The cause seems to be that the RTL818X_RX_CONF_MULTICAST flag doesn't
> have the desired effect.
>
> Fix the issue by setting RTL818X_RX_CONF_MONITOR instead, which puts the
> card into monitor mode and resolves the problem so that multicast frames
> are sucessfully passed to the kernel.
>
> The existence of the problem and the effectiveness of the solution has
> originally been confirmed on an 8187B based card with the USB id of
> 0bda:8197. Subsequent testing by Larry Finger on an 8187L based card,
> which follows the second (8187, i.e. "non-b") code path in the driver,
> has confirmed that the fix does not cause any noticeable regresssions
> there either.
>
> Signed-off-by: Nils Holland <nholland@tisys.org>

Acked-by: Larry Finger <Larry.Finger@lwfinger.net>

Thanks,

Larry

> ---
>  drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c | 16 +++++++---------
>  1 file changed, 7 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
> index 231f84db9ab0..56a8686cd367 100644
> --- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
> +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
> @@ -946,8 +946,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
>  		      (7 << 13 /* RX FIFO threshold NONE */) |
>  		      (7 << 10 /* MAX RX DMA */) |
>  		      RTL818X_RX_CONF_RX_AUTORESETPHY |
> -		      RTL818X_RX_CONF_ONLYERLPKT |
> -		      RTL818X_RX_CONF_MULTICAST;
> +		      RTL818X_RX_CONF_ONLYERLPKT;
>  		priv->rx_conf = reg;
>  		rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
>
> @@ -1319,12 +1318,11 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
>  		priv->rx_conf ^= RTL818X_RX_CONF_FCS;
>  	if (changed_flags & FIF_CONTROL)
>  		priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
> -	if (changed_flags & FIF_OTHER_BSS)
> -		priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
> -	if (*total_flags & FIF_ALLMULTI || multicast > 0)
> -		priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
> +	if (*total_flags & FIF_OTHER_BSS ||
> +	    *total_flags & FIF_ALLMULTI || multicast > 0)
> +		priv->rx_conf |= RTL818X_RX_CONF_MONITOR;
>  	else
> -		priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
> +		priv->rx_conf &= ~RTL818X_RX_CONF_MONITOR;
>
>  	*total_flags = 0;
>
> @@ -1332,10 +1330,10 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
>  		*total_flags |= FIF_FCSFAIL;
>  	if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
>  		*total_flags |= FIF_CONTROL;
> -	if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
> +	if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) {
>  		*total_flags |= FIF_OTHER_BSS;
> -	if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
>  		*total_flags |= FIF_ALLMULTI;
> +	}
>
>  	rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
>  }
>
Rafał Miłecki Feb. 20, 2017, 6:35 a.m. UTC | #2
On 02/20/2017 12:59 AM, Nils Holland wrote:
> The rtl8187 cards don't seem to receive multicast frames, which,
> among other things, makes them fail to receive RAs in IPv6 networks.
> The cause seems to be that the RTL818X_RX_CONF_MULTICAST flag doesn't
> have the desired effect.

AFAIU you have RTL8187B chipset card only, but above message describes this as
generic issue (including RTL8187 and RTL8187L).

Larry: were you able to reproduce this problem using RTL8187L? Is this
workaround needed for that chipset as well? I couldn't find clear statement.
Larry Finger Feb. 20, 2017, 4:18 p.m. UTC | #3
On 02/20/2017 12:35 AM, Rafał Miłecki wrote:
> On 02/20/2017 12:59 AM, Nils Holland wrote:
>> The rtl8187 cards don't seem to receive multicast frames, which,
>> among other things, makes them fail to receive RAs in IPv6 networks.
>> The cause seems to be that the RTL818X_RX_CONF_MULTICAST flag doesn't
>> have the desired effect.
>
> AFAIU you have RTL8187B chipset card only, but above message describes this as
> generic issue (including RTL8187 and RTL8187L).
>
> Larry: were you able to reproduce this problem using RTL8187L? Is this
> workaround needed for that chipset as well? I couldn't find clear statement.

Yes, the RTL8187L has the same problem as the RTL8187B. The fix is needed for both.

Larry
Rafał Miłecki Feb. 20, 2017, 5:50 p.m. UTC | #4
On 02/20/2017 05:18 PM, Larry Finger wrote:
> On 02/20/2017 12:35 AM, Rafał Miłecki wrote:
>> On 02/20/2017 12:59 AM, Nils Holland wrote:
>>> The rtl8187 cards don't seem to receive multicast frames, which,
>>> among other things, makes them fail to receive RAs in IPv6 networks.
>>> The cause seems to be that the RTL818X_RX_CONF_MULTICAST flag doesn't
>>> have the desired effect.
>>
>> AFAIU you have RTL8187B chipset card only, but above message describes this as
>> generic issue (including RTL8187 and RTL8187L).
>>
>> Larry: were you able to reproduce this problem using RTL8187L? Is this
>> workaround needed for that chipset as well? I couldn't find clear statement.
>
> Yes, the RTL8187L has the same problem as the RTL8187B. The fix is needed for both.

OK, thanks for clarifying!
Kalle Valo March 8, 2017, 3:08 p.m. UTC | #5
Nils Holland <nholland@tisys.org> wrote:
> The rtl8187 cards don't seem to receive multicast frames, which,
> among other things, makes them fail to receive RAs in IPv6 networks.
> The cause seems to be that the RTL818X_RX_CONF_MULTICAST flag doesn't
> have the desired effect.
> 
> Fix the issue by setting RTL818X_RX_CONF_MONITOR instead, which puts the
> card into monitor mode and resolves the problem so that multicast frames
> are sucessfully passed to the kernel.
> 
> The existence of the problem and the effectiveness of the solution has
> originally been confirmed on an 8187B based card with the USB id of
> 0bda:8197. Subsequent testing by Larry Finger on an 8187L based card,
> which follows the second (8187, i.e. "non-b") code path in the driver,
> has confirmed that the fix does not cause any noticeable regresssions
> there either.
> 
> Signed-off-by: Nils Holland <nholland@tisys.org>
> Acked-by: Larry Finger <Larry.Finger@lwfinger.net>

Patch applied to wireless-drivers-next.git, thanks.

3beb27028c44 rtl8187: Enable monitor mode to fix multicast reception
diff mbox

Patch

diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
index 231f84db9ab0..56a8686cd367 100644
--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
@@ -946,8 +946,7 @@  static int rtl8187_start(struct ieee80211_hw *dev)
 		      (7 << 13 /* RX FIFO threshold NONE */) |
 		      (7 << 10 /* MAX RX DMA */) |
 		      RTL818X_RX_CONF_RX_AUTORESETPHY |
-		      RTL818X_RX_CONF_ONLYERLPKT |
-		      RTL818X_RX_CONF_MULTICAST;
+		      RTL818X_RX_CONF_ONLYERLPKT;
 		priv->rx_conf = reg;
 		rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
 
@@ -1319,12 +1318,11 @@  static void rtl8187_configure_filter(struct ieee80211_hw *dev,
 		priv->rx_conf ^= RTL818X_RX_CONF_FCS;
 	if (changed_flags & FIF_CONTROL)
 		priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
-	if (changed_flags & FIF_OTHER_BSS)
-		priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
-	if (*total_flags & FIF_ALLMULTI || multicast > 0)
-		priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
+	if (*total_flags & FIF_OTHER_BSS ||
+	    *total_flags & FIF_ALLMULTI || multicast > 0)
+		priv->rx_conf |= RTL818X_RX_CONF_MONITOR;
 	else
-		priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
+		priv->rx_conf &= ~RTL818X_RX_CONF_MONITOR;
 
 	*total_flags = 0;
 
@@ -1332,10 +1330,10 @@  static void rtl8187_configure_filter(struct ieee80211_hw *dev,
 		*total_flags |= FIF_FCSFAIL;
 	if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
 		*total_flags |= FIF_CONTROL;
-	if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
+	if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) {
 		*total_flags |= FIF_OTHER_BSS;
-	if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
 		*total_flags |= FIF_ALLMULTI;
+	}
 
 	rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
 }