aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtlwifi/rtl8192cu
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2013-03-13 11:28:13 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-03-13 14:18:53 -0400
commit9437a248e7cac427c898bdb11bd1ac6844a1ead4 (patch)
treeffb975cba7c782c65d1e89353a138c29e91531d8 /drivers/net/wireless/rtlwifi/rtl8192cu
parent5818a46a999ad9546e68e8765a3ca1d9d87f9b4a (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>
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192cu')
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c87
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
1378void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 1378void 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
1385static 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 *)(&reg_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 *)(&reg_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 *)(&reg_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 *) (&reg_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 *)(&reg_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 *)(&reg_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 *) (&reg_rcr));
1411 _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0);
1440 } 1412 }
1441} 1413}
1442 1414
1415/*========================================================================== */
1416
1443int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) 1417int 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