Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless

John W. Linville says:

====================
On the NFC bits, Samuel says:

"With this one we have:

- A fix for properly decreasing socket ack log.
- A timer and works cleanup upon NFC device removal.
- A monitoroing socket cleanup round from llcp_socket_release.
- A proper error report to pending sockets upon NFC device removal."

Regarding the Bluetooth bits, Gustavo says:

"I have these two patches for 3.9, these add support for two more devices to
the bluetooth drivers."

Along with those, we have a few wireless driver fixes...

Bing Zhao provides an mwifiex to prevent an out-of-bounds memory
access.

John Crispin offers a Kconfig fix to enable some otherwise dead code
in rt2x00.  The correct symbols were added in -rc1 through a different
tree, but the symbols for enabling the wireless driver didn't match.

Larry Finger brings an rtlwifi fix for a scheduling while atomic bug,
and another fix for a reassociation problem caused by failing to
clear the BSSID after a disconnect.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2013-03-17 12:26:18 -04:00
commit c62dce6126
8 changed files with 116 additions and 84 deletions

View file

@ -74,8 +74,10 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3004) },
{ USB_DEVICE(0x0CF3, 0x3008) },
{ USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x04CA, 0x3004) },
{ USB_DEVICE(0x04CA, 0x3005) },
{ USB_DEVICE(0x04CA, 0x3006) },
{ USB_DEVICE(0x04CA, 0x3008) },
@ -106,8 +108,10 @@ static struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },

View file

@ -132,8 +132,10 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros 3012 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },

View file

@ -1117,10 +1117,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
adhoc_join->bss_descriptor.bssid,
adhoc_join->bss_descriptor.ssid);
for (i = 0; bss_desc->supported_rates[i] &&
i < MWIFIEX_SUPPORTED_RATES;
i++)
;
for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
bss_desc->supported_rates[i]; i++)
;
rates_size = i;
/* Copy Data Rates from the Rates recorded in scan response */

View file

@ -55,10 +55,10 @@ config RT61PCI
config RT2800PCI
tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
depends on PCI || RALINK_RT288X || RALINK_RT305X
depends on PCI || SOC_RT288X || SOC_RT305X
select RT2800_LIB
select RT2X00_LIB_PCI if PCI
select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X
select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
select RT2X00_LIB_FIRMWARE
select RT2X00_LIB_CRYPTO
select CRC_CCITT

View file

@ -89,7 +89,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
}
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
{
void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
@ -107,7 +107,7 @@ static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
{
return -ENOMEM;
}
#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
#ifdef CONFIG_PCI
static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@ -1177,7 +1177,7 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
#endif /* CONFIG_PCI */
MODULE_LICENSE("GPL");
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
static int rt2800soc_probe(struct platform_device *pdev)
{
return rt2x00soc_probe(pdev, &rt2800pci_ops);
@ -1194,7 +1194,7 @@ static struct platform_driver rt2800soc_driver = {
.suspend = rt2x00soc_suspend,
.resume = rt2x00soc_resume,
};
#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
#ifdef CONFIG_PCI
static int rt2800pci_probe(struct pci_dev *pci_dev,
@ -1217,7 +1217,7 @@ static int __init rt2800pci_init(void)
{
int ret = 0;
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
ret = platform_driver_register(&rt2800soc_driver);
if (ret)
return ret;
@ -1225,7 +1225,7 @@ static int __init rt2800pci_init(void)
#ifdef CONFIG_PCI
ret = pci_register_driver(&rt2800pci_driver);
if (ret) {
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
platform_driver_unregister(&rt2800soc_driver);
#endif
return ret;
@ -1240,7 +1240,7 @@ static void __exit rt2800pci_exit(void)
#ifdef CONFIG_PCI
pci_unregister_driver(&rt2800pci_driver);
#endif
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
platform_driver_unregister(&rt2800soc_driver);
#endif
}

View file

@ -1377,74 +1377,57 @@ void rtl92cu_card_disable(struct ieee80211_hw *hw)
void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
{
/* dummy routine needed for callback from rtl_op_configure_filter() */
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
if (rtlpriv->psc.rfpwr_state != ERFON)
return;
if (check_bssid) {
u8 tmp;
if (IS_NORMAL_CHIP(rtlhal->version)) {
reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
tmp = BIT(4);
} else {
reg_rcr |= RCR_CBSSID;
tmp = BIT(4) | BIT(5);
}
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
(u8 *) (&reg_rcr));
_rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp);
} else {
u8 tmp;
if (IS_NORMAL_CHIP(rtlhal->version)) {
reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
tmp = BIT(4);
} else {
reg_rcr &= ~RCR_CBSSID;
tmp = BIT(4) | BIT(5);
}
reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_RCR, (u8 *) (&reg_rcr));
_rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0);
}
}
/*========================================================================== */
static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw,
enum nl80211_iftype type)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u8 filterout_non_associated_bssid = false;
switch (type) {
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_STATION:
filterout_non_associated_bssid = true;
break;
case NL80211_IFTYPE_UNSPECIFIED:
case NL80211_IFTYPE_AP:
default:
break;
}
if (filterout_non_associated_bssid) {
if (IS_NORMAL_CHIP(rtlhal->version)) {
switch (rtlphy->current_io_type) {
case IO_CMD_RESUME_DM_BY_SCAN:
reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_RCR, (u8 *)(&reg_rcr));
/* enable update TSF */
_rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
break;
case IO_CMD_PAUSE_DM_BY_SCAN:
reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_RCR, (u8 *)(&reg_rcr));
/* disable update TSF */
_rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
break;
}
} else {
reg_rcr |= (RCR_CBSSID);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
(u8 *)(&reg_rcr));
_rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5)));
}
} else if (filterout_non_associated_bssid == false) {
if (IS_NORMAL_CHIP(rtlhal->version)) {
reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
(u8 *)(&reg_rcr));
_rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
} else {
reg_rcr &= (~RCR_CBSSID);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
(u8 *)(&reg_rcr));
_rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0);
}
}
}
int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (_rtl92cu_set_media_status(hw, type))
return -EOPNOTSUPP;
_rtl92cu_set_check_bssid(hw, type);
if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
if (type != NL80211_IFTYPE_AP)
rtl92cu_set_check_bssid(hw, true);
} else {
rtl92cu_set_check_bssid(hw, false);
}
return 0;
}
@ -2058,8 +2041,6 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
(shortgi_rate << 4) | (shortgi_rate);
}
rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
rtl_read_dword(rtlpriv, REG_ARFR0));
}
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)

View file

@ -68,7 +68,8 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock)
}
}
static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen,
int err)
{
struct sock *sk;
struct hlist_node *tmp;
@ -100,7 +101,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
nfc_llcp_accept_unlink(accept_sk);
if (err)
accept_sk->sk_err = err;
accept_sk->sk_state = LLCP_CLOSED;
accept_sk->sk_state_change(sk);
bh_unlock_sock(accept_sk);
@ -123,7 +127,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
continue;
}
if (err)
sk->sk_err = err;
sk->sk_state = LLCP_CLOSED;
sk->sk_state_change(sk);
bh_unlock_sock(sk);
@ -133,6 +140,36 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
}
write_unlock(&local->sockets.lock);
/*
* If we want to keep the listening sockets alive,
* we don't touch the RAW ones.
*/
if (listen == true)
return;
write_lock(&local->raw_sockets.lock);
sk_for_each_safe(sk, tmp, &local->raw_sockets.head) {
llcp_sock = nfc_llcp_sock(sk);
bh_lock_sock(sk);
nfc_llcp_socket_purge(llcp_sock);
if (err)
sk->sk_err = err;
sk->sk_state = LLCP_CLOSED;
sk->sk_state_change(sk);
bh_unlock_sock(sk);
sock_orphan(sk);
sk_del_node_init(sk);
}
write_unlock(&local->raw_sockets.lock);
}
struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
@ -142,6 +179,17 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
return local;
}
static void local_cleanup(struct nfc_llcp_local *local, bool listen)
{
nfc_llcp_socket_release(local, listen, ENXIO);
del_timer_sync(&local->link_timer);
skb_queue_purge(&local->tx_queue);
cancel_work_sync(&local->tx_work);
cancel_work_sync(&local->rx_work);
cancel_work_sync(&local->timeout_work);
kfree_skb(local->rx_pending);
}
static void local_release(struct kref *ref)
{
struct nfc_llcp_local *local;
@ -149,13 +197,7 @@ static void local_release(struct kref *ref)
local = container_of(ref, struct nfc_llcp_local, ref);
list_del(&local->list);
nfc_llcp_socket_release(local, false);
del_timer_sync(&local->link_timer);
skb_queue_purge(&local->tx_queue);
cancel_work_sync(&local->tx_work);
cancel_work_sync(&local->rx_work);
cancel_work_sync(&local->timeout_work);
kfree_skb(local->rx_pending);
local_cleanup(local, false);
kfree(local);
}
@ -1348,7 +1390,7 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
return;
/* Close and purge all existing sockets */
nfc_llcp_socket_release(local, true);
nfc_llcp_socket_release(local, true, 0);
}
void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
@ -1427,6 +1469,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
return;
}
local_cleanup(local, false);
nfc_llcp_local_put(local);
}

View file

@ -278,6 +278,8 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
pr_debug("Returning sk state %d\n", sk->sk_state);
sk_acceptq_removed(parent);
return sk;
}