aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
authorAlbert Herranz <albert_herranz@yahoo.es>2009-09-10 13:34:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-09-23 11:35:43 -0400
commit3dbba8e281552da640080f08a0f127d48456669f (patch)
tree111f1db7448c7e3214e02e6d09d7e8f285727188 /drivers/net/wireless/b43/main.c
parenta78b3bb2f3ab9afcf78dbcff18fd7bf900c7c27e (diff)
b43: Add Soft-MAC SDIO device support
This adds support for Soft-MAC SDIO devices to b43. The driver still lacks some fixes for SDIO devices, so it's currently marked as BROKEN. Signed-off-by: Albert Herranz <albert_herranz@yahoo.es> Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c76
1 files changed, 62 insertions, 14 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 2984a915f8b1..950a838757c4 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -8,6 +8,9 @@
8 Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> 8 Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
9 Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> 9 Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10 10
11 SDIO support
12 Copyright (c) 2009 Albert Herranz <albert_herranz@yahoo.es>
13
11 Some parts of the code in this file are derived from the ipw2200 14 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation. 15 driver Copyright(c) 2003 - 2004 Intel Corporation.
13 16
@@ -53,6 +56,8 @@
53#include "xmit.h" 56#include "xmit.h"
54#include "lo.h" 57#include "lo.h"
55#include "pcmcia.h" 58#include "pcmcia.h"
59#include "sdio.h"
60#include <linux/mmc/sdio_func.h>
56 61
57MODULE_DESCRIPTION("Broadcom B43 wireless driver"); 62MODULE_DESCRIPTION("Broadcom B43 wireless driver");
58MODULE_AUTHOR("Martin Langer"); 63MODULE_AUTHOR("Martin Langer");
@@ -1587,7 +1592,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
1587 mutex_lock(&wl->mutex); 1592 mutex_lock(&wl->mutex);
1588 dev = wl->current_dev; 1593 dev = wl->current_dev;
1589 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { 1594 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
1590 if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) { 1595 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
1591 /* wl->mutex is enough. */ 1596 /* wl->mutex is enough. */
1592 b43_do_beacon_update_trigger_work(dev); 1597 b43_do_beacon_update_trigger_work(dev);
1593 mmiowb(); 1598 mmiowb();
@@ -1905,6 +1910,27 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1905 return ret; 1910 return ret;
1906} 1911}
1907 1912
1913/* SDIO interrupt handler. This runs in process context. */
1914static void b43_sdio_interrupt_handler(struct b43_wldev *dev)
1915{
1916 struct b43_wl *wl = dev->wl;
1917 struct sdio_func *func = dev->dev->bus->host_sdio;
1918 irqreturn_t ret;
1919
1920 if (unlikely(b43_status(dev) < B43_STAT_STARTED))
1921 return;
1922
1923 mutex_lock(&wl->mutex);
1924 sdio_release_host(func);
1925
1926 ret = b43_do_interrupt(dev);
1927 if (ret == IRQ_WAKE_THREAD)
1928 b43_do_interrupt_thread(dev);
1929
1930 sdio_claim_host(func);
1931 mutex_unlock(&wl->mutex);
1932}
1933
1908void b43_do_release_fw(struct b43_firmware_file *fw) 1934void b43_do_release_fw(struct b43_firmware_file *fw)
1909{ 1935{
1910 release_firmware(fw->data); 1936 release_firmware(fw->data);
@@ -3824,7 +3850,7 @@ redo:
3824 3850
3825 /* Disable interrupts on the device. */ 3851 /* Disable interrupts on the device. */
3826 b43_set_status(dev, B43_STAT_INITIALIZED); 3852 b43_set_status(dev, B43_STAT_INITIALIZED);
3827 if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) { 3853 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
3828 /* wl->mutex is locked. That is enough. */ 3854 /* wl->mutex is locked. That is enough. */
3829 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); 3855 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
3830 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ 3856 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
@@ -3854,7 +3880,10 @@ redo:
3854 dev_kfree_skb(skb_dequeue(&wl->tx_queue)); 3880 dev_kfree_skb(skb_dequeue(&wl->tx_queue));
3855 3881
3856 b43_mac_suspend(dev); 3882 b43_mac_suspend(dev);
3857 free_irq(dev->dev->irq, dev); 3883 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO)
3884 b43_sdio_free_irq(dev);
3885 else
3886 free_irq(dev->dev->irq, dev);
3858 b43_leds_exit(dev); 3887 b43_leds_exit(dev);
3859 b43dbg(wl, "Wireless interface stopped\n"); 3888 b43dbg(wl, "Wireless interface stopped\n");
3860 3889
@@ -3869,12 +3898,20 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3869 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); 3898 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
3870 3899
3871 drain_txstatus_queue(dev); 3900 drain_txstatus_queue(dev);
3872 err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, 3901 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
3873 b43_interrupt_thread_handler, 3902 err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);
3874 IRQF_SHARED, KBUILD_MODNAME, dev); 3903 if (err) {
3875 if (err) { 3904 b43err(dev->wl, "Cannot request SDIO IRQ\n");
3876 b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq); 3905 goto out;
3877 goto out; 3906 }
3907 } else {
3908 err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
3909 b43_interrupt_thread_handler,
3910 IRQF_SHARED, KBUILD_MODNAME, dev);
3911 if (err) {
3912 b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
3913 goto out;
3914 }
3878 } 3915 }
3879 3916
3880 /* We are ready to run. */ 3917 /* We are ready to run. */
@@ -4266,7 +4303,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4266 /* Maximum Contention Window */ 4303 /* Maximum Contention Window */
4267 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 4304 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
4268 4305
4269 if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || B43_FORCE_PIO) { 4306 if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
4307 (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
4308 B43_FORCE_PIO) {
4270 dev->__using_pio_transfers = 1; 4309 dev->__using_pio_transfers = 1;
4271 err = b43_pio_init(dev); 4310 err = b43_pio_init(dev);
4272 } else { 4311 } else {
@@ -4942,7 +4981,7 @@ static struct ssb_driver b43_ssb_driver = {
4942static void b43_print_driverinfo(void) 4981static void b43_print_driverinfo(void)
4943{ 4982{
4944 const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", 4983 const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "",
4945 *feat_leds = ""; 4984 *feat_leds = "", *feat_sdio = "";
4946 4985
4947#ifdef CONFIG_B43_PCI_AUTOSELECT 4986#ifdef CONFIG_B43_PCI_AUTOSELECT
4948 feat_pci = "P"; 4987 feat_pci = "P";
@@ -4956,11 +4995,14 @@ static void b43_print_driverinfo(void)
4956#ifdef CONFIG_B43_LEDS 4995#ifdef CONFIG_B43_LEDS
4957 feat_leds = "L"; 4996 feat_leds = "L";
4958#endif 4997#endif
4998#ifdef CONFIG_B43_SDIO
4999 feat_sdio = "S";
5000#endif
4959 printk(KERN_INFO "Broadcom 43xx driver loaded " 5001 printk(KERN_INFO "Broadcom 43xx driver loaded "
4960 "[ Features: %s%s%s%s, Firmware-ID: " 5002 "[ Features: %s%s%s%s%s, Firmware-ID: "
4961 B43_SUPPORTED_FIRMWARE_ID " ]\n", 5003 B43_SUPPORTED_FIRMWARE_ID " ]\n",
4962 feat_pci, feat_pcmcia, feat_nphy, 5004 feat_pci, feat_pcmcia, feat_nphy,
4963 feat_leds); 5005 feat_leds, feat_sdio);
4964} 5006}
4965 5007
4966static int __init b43_init(void) 5008static int __init b43_init(void)
@@ -4971,13 +5013,18 @@ static int __init b43_init(void)
4971 err = b43_pcmcia_init(); 5013 err = b43_pcmcia_init();
4972 if (err) 5014 if (err)
4973 goto err_dfs_exit; 5015 goto err_dfs_exit;
4974 err = ssb_driver_register(&b43_ssb_driver); 5016 err = b43_sdio_init();
4975 if (err) 5017 if (err)
4976 goto err_pcmcia_exit; 5018 goto err_pcmcia_exit;
5019 err = ssb_driver_register(&b43_ssb_driver);
5020 if (err)
5021 goto err_sdio_exit;
4977 b43_print_driverinfo(); 5022 b43_print_driverinfo();
4978 5023
4979 return err; 5024 return err;
4980 5025
5026err_sdio_exit:
5027 b43_sdio_exit();
4981err_pcmcia_exit: 5028err_pcmcia_exit:
4982 b43_pcmcia_exit(); 5029 b43_pcmcia_exit();
4983err_dfs_exit: 5030err_dfs_exit:
@@ -4988,6 +5035,7 @@ err_dfs_exit:
4988static void __exit b43_exit(void) 5035static void __exit b43_exit(void)
4989{ 5036{
4990 ssb_driver_unregister(&b43_ssb_driver); 5037 ssb_driver_unregister(&b43_ssb_driver);
5038 b43_sdio_exit();
4991 b43_pcmcia_exit(); 5039 b43_pcmcia_exit();
4992 b43_debugfs_exit(); 5040 b43_debugfs_exit();
4993} 5041}