diff options
| author | Larry Finger <Larry.Finger@lwfinger.net> | 2013-03-13 11:28:13 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2013-03-13 14:18:53 -0400 |
| commit | 9437a248e7cac427c898bdb11bd1ac6844a1ead4 (patch) | |
| tree | ffb975cba7c782c65d1e89353a138c29e91531d8 | |
| parent | 5818a46a999ad9546e68e8765a3ca1d9d87f9b4a (diff) | |
rtlwifi: rtl8192cu: Fix problem that prevents reassociation
The driver was failing to clear the BSSID when a disconnect happened. That
prevented a reconnection. This problem is reported at
https://bugzilla.redhat.com/show_bug.cgi?id=789605,
https://bugzilla.redhat.com/show_bug.cgi?id=866786,
https://bugzilla.redhat.com/show_bug.cgi?id=906734, and
https://bugzilla.kernel.org/show_bug.cgi?id=46171.
Thanks to Jussi Kivilinna for making the critical observation
that led to the solution.
Reported-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Tested-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Tested-by: Alessandro Lannocca <alessandro.lannocca@gmail.com>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Stable <stable@vger.kernel.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 87 |
1 files changed, 35 insertions, 52 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 3c6e18c38e30..c08d0f4c5f3d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
| @@ -1377,74 +1377,57 @@ void rtl92cu_card_disable(struct ieee80211_hw *hw) | |||
| 1377 | 1377 | ||
| 1378 | void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) | 1378 | void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) |
| 1379 | { | 1379 | { |
| 1380 | /* dummy routine needed for callback from rtl_op_configure_filter() */ | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | /*========================================================================== */ | ||
| 1384 | |||
| 1385 | static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw, | ||
| 1386 | enum nl80211_iftype type) | ||
| 1387 | { | ||
| 1388 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1380 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 1389 | u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); | ||
| 1390 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | 1381 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); |
| 1391 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 1382 | u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); |
| 1392 | u8 filterout_non_associated_bssid = false; | ||
| 1393 | 1383 | ||
| 1394 | switch (type) { | 1384 | if (rtlpriv->psc.rfpwr_state != ERFON) |
| 1395 | case NL80211_IFTYPE_ADHOC: | 1385 | return; |
| 1396 | case NL80211_IFTYPE_STATION: | 1386 | |
| 1397 | filterout_non_associated_bssid = true; | 1387 | if (check_bssid) { |
| 1398 | break; | 1388 | u8 tmp; |
| 1399 | case NL80211_IFTYPE_UNSPECIFIED: | ||
| 1400 | case NL80211_IFTYPE_AP: | ||
| 1401 | default: | ||
| 1402 | break; | ||
| 1403 | } | ||
| 1404 | if (filterout_non_associated_bssid) { | ||
| 1405 | if (IS_NORMAL_CHIP(rtlhal->version)) { | 1389 | if (IS_NORMAL_CHIP(rtlhal->version)) { |
| 1406 | switch (rtlphy->current_io_type) { | 1390 | reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); |
| 1407 | case IO_CMD_RESUME_DM_BY_SCAN: | 1391 | tmp = BIT(4); |
| 1408 | reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); | ||
| 1409 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
| 1410 | HW_VAR_RCR, (u8 *)(®_rcr)); | ||
| 1411 | /* enable update TSF */ | ||
| 1412 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); | ||
| 1413 | break; | ||
| 1414 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
| 1415 | reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); | ||
| 1416 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
| 1417 | HW_VAR_RCR, (u8 *)(®_rcr)); | ||
| 1418 | /* disable update TSF */ | ||
| 1419 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); | ||
| 1420 | break; | ||
| 1421 | } | ||
| 1422 | } else { | 1392 | } else { |
| 1423 | reg_rcr |= (RCR_CBSSID); | 1393 | reg_rcr |= RCR_CBSSID; |
| 1424 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, | 1394 | tmp = BIT(4) | BIT(5); |
| 1425 | (u8 *)(®_rcr)); | ||
| 1426 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5))); | ||
| 1427 | } | 1395 | } |
| 1428 | } else if (filterout_non_associated_bssid == false) { | 1396 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, |
| 1397 | (u8 *) (®_rcr)); | ||
| 1398 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp); | ||
| 1399 | } else { | ||
| 1400 | u8 tmp; | ||
| 1429 | if (IS_NORMAL_CHIP(rtlhal->version)) { | 1401 | if (IS_NORMAL_CHIP(rtlhal->version)) { |
| 1430 | reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); | 1402 | reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); |
| 1431 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, | 1403 | tmp = BIT(4); |
| 1432 | (u8 *)(®_rcr)); | ||
| 1433 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); | ||
| 1434 | } else { | 1404 | } else { |
| 1435 | reg_rcr &= (~RCR_CBSSID); | 1405 | reg_rcr &= ~RCR_CBSSID; |
| 1436 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, | 1406 | tmp = BIT(4) | BIT(5); |
| 1437 | (u8 *)(®_rcr)); | ||
| 1438 | _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0); | ||
| 1439 | } | 1407 | } |
| 1408 | reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); | ||
| 1409 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
| 1410 | HW_VAR_RCR, (u8 *) (®_rcr)); | ||
| 1411 | _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0); | ||
| 1440 | } | 1412 | } |
| 1441 | } | 1413 | } |
| 1442 | 1414 | ||
| 1415 | /*========================================================================== */ | ||
| 1416 | |||
| 1443 | int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) | 1417 | int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) |
| 1444 | { | 1418 | { |
| 1419 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
| 1420 | |||
| 1445 | if (_rtl92cu_set_media_status(hw, type)) | 1421 | if (_rtl92cu_set_media_status(hw, type)) |
| 1446 | return -EOPNOTSUPP; | 1422 | return -EOPNOTSUPP; |
| 1447 | _rtl92cu_set_check_bssid(hw, type); | 1423 | |
| 1424 | if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { | ||
| 1425 | if (type != NL80211_IFTYPE_AP) | ||
| 1426 | rtl92cu_set_check_bssid(hw, true); | ||
| 1427 | } else { | ||
| 1428 | rtl92cu_set_check_bssid(hw, false); | ||
| 1429 | } | ||
| 1430 | |||
| 1448 | return 0; | 1431 | return 0; |
| 1449 | } | 1432 | } |
| 1450 | 1433 | ||
