aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/at76c50x-usb.c
diff options
context:
space:
mode:
authorSebastian Smolorz <Sebastian.Smolorz@gmx.de>2010-06-22 10:55:17 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-24 15:42:33 -0400
commita185045c8da1ec6627236b4ade0d949b15da43b3 (patch)
tree20d10b53e3cba7aa32df18ee9b073dc9e4b37ab3 /drivers/net/wireless/at76c50x-usb.c
parent41b4b289adaaf53e563a2cde17c45c492608edb0 (diff)
at76c50x-usb: Extract bssid from authentication frame
The driver at76c50x-usb is unable to authenticate with an AP since kernel 2.6.31 for the following reason: The join command of the firmware needs to be sent with the right bssid before any transmission can start. Before kernel 2.6.31 mac80211 informed its drivers about the changing bssid early enough for at76c50x-usb but during the development of 2.6.31 mac80211's behaviour changed. Now a new bssid is set after the association. This patch changes the tx routine of the driver at76c50x-usb in such a way that a new bssid is extracted from an authentication frame and the join command with that bssid is processed. Signed-off-by: Sebastian Smolorz <sesmo@gmx.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/at76c50x-usb.c')
-rw-r--r--drivers/net/wireless/at76c50x-usb.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index cb3d4b70bcbc..98328b7f8332 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -7,6 +7,7 @@
7 * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com> 7 * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
8 * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org> 8 * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
9 * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi> 9 * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi>
10 * Copyright (c) 2010 Sebastian Smolorz <sesmo@gmx.net>
10 * 11 *
11 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as 13 * modify it under the terms of the GNU General Public License as
@@ -1685,6 +1686,22 @@ static int at76_join(struct at76_priv *priv)
1685 return 0; 1686 return 0;
1686} 1687}
1687 1688
1689static void at76_work_join_bssid(struct work_struct *work)
1690{
1691 struct at76_priv *priv = container_of(work, struct at76_priv,
1692 work_join_bssid);
1693
1694 if (priv->device_unplugged)
1695 return;
1696
1697 mutex_lock(&priv->mtx);
1698
1699 if (is_valid_ether_addr(priv->bssid))
1700 at76_join(priv);
1701
1702 mutex_unlock(&priv->mtx);
1703}
1704
1688static void at76_mac80211_tx_callback(struct urb *urb) 1705static void at76_mac80211_tx_callback(struct urb *urb)
1689{ 1706{
1690 struct at76_priv *priv = urb->context; 1707 struct at76_priv *priv = urb->context;
@@ -1722,6 +1739,7 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1722 struct at76_priv *priv = hw->priv; 1739 struct at76_priv *priv = hw->priv;
1723 struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; 1740 struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
1724 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1741 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1742 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1725 int padding, submit_len, ret; 1743 int padding, submit_len, ret;
1726 1744
1727 at76_dbg(DBG_MAC80211, "%s()", __func__); 1745 at76_dbg(DBG_MAC80211, "%s()", __func__);
@@ -1732,6 +1750,21 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1732 return NETDEV_TX_BUSY; 1750 return NETDEV_TX_BUSY;
1733 } 1751 }
1734 1752
1753 /* The following code lines are important when the device is going to
1754 * authenticate with a new bssid. The driver must send CMD_JOIN before
1755 * an authentication frame is transmitted. For this to succeed, the
1756 * correct bssid of the AP must be known. As mac80211 does not inform
1757 * drivers about the bssid prior to the authentication process the
1758 * following workaround is necessary. If the TX frame is an
1759 * authentication frame extract the bssid and send the CMD_JOIN. */
1760 if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) {
1761 if (compare_ether_addr(priv->bssid, mgmt->bssid)) {
1762 memcpy(priv->bssid, mgmt->bssid, ETH_ALEN);
1763 ieee80211_queue_work(hw, &priv->work_join_bssid);
1764 return NETDEV_TX_BUSY;
1765 }
1766 }
1767
1735 ieee80211_stop_queues(hw); 1768 ieee80211_stop_queues(hw);
1736 1769
1737 at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */ 1770 at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
@@ -1806,6 +1839,7 @@ static void at76_mac80211_stop(struct ieee80211_hw *hw)
1806 at76_dbg(DBG_MAC80211, "%s()", __func__); 1839 at76_dbg(DBG_MAC80211, "%s()", __func__);
1807 1840
1808 cancel_delayed_work(&priv->dwork_hw_scan); 1841 cancel_delayed_work(&priv->dwork_hw_scan);
1842 cancel_work_sync(&priv->work_join_bssid);
1809 cancel_work_sync(&priv->work_set_promisc); 1843 cancel_work_sync(&priv->work_set_promisc);
1810 1844
1811 mutex_lock(&priv->mtx); 1845 mutex_lock(&priv->mtx);
@@ -2107,6 +2141,7 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
2107 mutex_init(&priv->mtx); 2141 mutex_init(&priv->mtx);
2108 INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc); 2142 INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
2109 INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx); 2143 INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
2144 INIT_WORK(&priv->work_join_bssid, at76_work_join_bssid);
2110 INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan); 2145 INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
2111 2146
2112 tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0); 2147 tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0);
@@ -2508,5 +2543,6 @@ MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
2508MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"); 2543MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
2509MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>"); 2544MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>");
2510MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>"); 2545MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>");
2546MODULE_AUTHOR("Sebastian Smolorz <sesmo@gmx.net>");
2511MODULE_DESCRIPTION(DRIVER_DESC); 2547MODULE_DESCRIPTION(DRIVER_DESC);
2512MODULE_LICENSE("GPL"); 2548MODULE_LICENSE("GPL");