Commit 3beb2702 authored by Nils Holland's avatar Nils Holland Committed by Kalle Valo

rtl8187: Enable monitor mode to fix multicast reception

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: default avatarNils Holland <nholland@tisys.org>
Acked-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent dd35cc08
...@@ -946,8 +946,7 @@ static int rtl8187_start(struct ieee80211_hw *dev) ...@@ -946,8 +946,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
(7 << 13 /* RX FIFO threshold NONE */) | (7 << 13 /* RX FIFO threshold NONE */) |
(7 << 10 /* MAX RX DMA */) | (7 << 10 /* MAX RX DMA */) |
RTL818X_RX_CONF_RX_AUTORESETPHY | RTL818X_RX_CONF_RX_AUTORESETPHY |
RTL818X_RX_CONF_ONLYERLPKT | RTL818X_RX_CONF_ONLYERLPKT;
RTL818X_RX_CONF_MULTICAST;
priv->rx_conf = reg; priv->rx_conf = reg;
rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
...@@ -1319,12 +1318,11 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev, ...@@ -1319,12 +1318,11 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
priv->rx_conf ^= RTL818X_RX_CONF_FCS; priv->rx_conf ^= RTL818X_RX_CONF_FCS;
if (changed_flags & FIF_CONTROL) if (changed_flags & FIF_CONTROL)
priv->rx_conf ^= RTL818X_RX_CONF_CTRL; priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
if (changed_flags & FIF_OTHER_BSS) if (*total_flags & FIF_OTHER_BSS ||
priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; *total_flags & FIF_ALLMULTI || multicast > 0)
if (*total_flags & FIF_ALLMULTI || multicast > 0) priv->rx_conf |= RTL818X_RX_CONF_MONITOR;
priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
else else
priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; priv->rx_conf &= ~RTL818X_RX_CONF_MONITOR;
*total_flags = 0; *total_flags = 0;
...@@ -1332,10 +1330,10 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev, ...@@ -1332,10 +1330,10 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
*total_flags |= FIF_FCSFAIL; *total_flags |= FIF_FCSFAIL;
if (priv->rx_conf & RTL818X_RX_CONF_CTRL) if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
*total_flags |= FIF_CONTROL; *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; *total_flags |= FIF_OTHER_BSS;
if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
*total_flags |= FIF_ALLMULTI; *total_flags |= FIF_ALLMULTI;
}
rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf); rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment