From 48de1a17fc41613b7e9d61037fa989256d04234f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 2 Mar 2012 13:21:22 -0600 Subject: rtlwifi: Detect misread of end-point count In the unlikely event of a misread of the USB end point count, the driver generates a divide fault. To prevent this, add a check of the value returned by _rtl_usb_init(). In addition, add some logging to indicate why the condition occurred. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/usb.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/rtlwifi') diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index ffcf89fe45e4..b0eee0eb5679 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -346,9 +346,14 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, pep_desc->bInterval); } - if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) - return -EINVAL ; - + if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) { + pr_err("Too few input end points found\n"); + return -EINVAL; + } + if (rtlusb->out_ep_nums == 0) { + pr_err("No output end points found\n"); + return -EINVAL; + } /* usb endpoint mapping */ err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; @@ -976,6 +981,8 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, } rtlpriv->cfg->ops->init_sw_leds(hw); err = _rtl_usb_init(hw); + if (err) + goto error_out; err = _rtl_usb_init_sw(hw); /* Init mac80211 sw */ err = rtl_init_core(hw); -- cgit v1.2.3 From 8f526ab4aa1b145bda2baf56e223050c7ef3e1b0 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 2 Mar 2012 13:22:46 -0600 Subject: rtlwifi: Remove extraneous value return In usb.c, routine _rtl_usb_init_sw() always returns 0, and rtl_usb_probe() never checks the returned value. Thus we can change _rtl_usb_init_sw() to a void routine. In addition, remove the underscore at the beginning of the name of the routine. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/usb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/rtlwifi') diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index b0eee0eb5679..2e1e352864bb 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -362,7 +362,7 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) return err; } -static int _rtl_usb_init_sw(struct ieee80211_hw *hw) +static void rtl_usb_init_sw(struct ieee80211_hw *hw) { struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -397,7 +397,6 @@ static int _rtl_usb_init_sw(struct ieee80211_hw *hw) /* HIMR_EX - turn all on */ rtlusb->irq_mask[1] = 0xFFFFFFFF; rtlusb->disableHWSM = true; - return 0; } #define __RADIO_TAP_SIZE_RSV 32 @@ -983,7 +982,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, err = _rtl_usb_init(hw); if (err) goto error_out; - err = _rtl_usb_init_sw(hw); + rtl_usb_init_sw(hw); /* Init mac80211 sw */ err = rtl_init_core(hw); if (err) { -- cgit v1.2.3 From ebecdcc12fed5d3c81853dea61a0a78a5aefab52 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 2 Mar 2012 15:23:36 -0600 Subject: rtlwifi: rtl8192c: Prevent sleeping from invalid context in rtl8192cu When driver rtl8192cu is used with the debug level set to 3 or greater, the result is "sleeping function called from invalid context" due to an rcu_read_lock() call in the DM refresh routine in driver rtl8192c. This lock is not necessary as the USB driver does not use the struct being protected, thus the lock is set only when a PCI interface is active. This bug is reported in https://bugzilla.kernel.org/show_bug.cgi?id=42775. Reported-by: Ronald Wahl Tested-by: Ronald Wahl Signed-off-by: Larry Finger Cc: Stable Cc: Ronald Wahl Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/rtlwifi') diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index cb5535cf3ae2..8646ff2a55ce 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -1201,13 +1201,18 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) "PreState = %d, CurState = %d\n", p_ra->pre_ratr_state, p_ra->ratr_state); - rcu_read_lock(); - sta = ieee80211_find_sta(mac->vif, mac->bssid); + /* Only the PCI card uses sta in the update rate table + * callback routine */ + if (rtlhal->interface == INTF_PCI) { + rcu_read_lock(); + sta = ieee80211_find_sta(mac->vif, mac->bssid); + } rtlpriv->cfg->ops->update_rate_tbl(hw, sta, p_ra->ratr_state); p_ra->pre_ratr_state = p_ra->ratr_state; - rcu_read_unlock(); + if (rtlhal->interface == INTF_PCI) + rcu_read_unlock(); } } } -- cgit v1.2.3 From a9b89e2567c743483e6354f64d7a7e3a8c101e9e Mon Sep 17 00:00:00 2001 From: Jingjun Wu Date: Fri, 2 Mar 2012 20:52:14 -0600 Subject: rtlwifi: rtl8192ce: Fix loss of receive performance Driver rtl8192ce when used with the RTL8188CE device would start at about 20 Mbps on a 54 Mbps connection, but quickly drop to 1 Mbps. One of the symptoms is that the AP would need to retransmit each packet 4 of 5 times before the driver would acknowledge it. Recovery is possible only by unloading and reloading the driver. This problem was reported at https://bugzilla.redhat.com/show_bug.cgi?id=770207. The problem is due to a missing update of the gain setting. Signed-off-by: Jingjun Wu Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net/wireless/rtlwifi') diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 8646ff2a55ce..d8d73dbb5780 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -520,6 +520,10 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, dm_digtable.backoff_val); + dm_digtable.cur_igvalue += 2; + if (dm_digtable.cur_igvalue > 0x3f) + dm_digtable.cur_igvalue = 0x3f; + if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, dm_digtable.cur_igvalue); -- cgit v1.2.3