From e4d6b7951812d98417feb10784e400e253caf633 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 18 Sep 2007 15:39:42 -0400 Subject: [B43]: add mac80211-based driver for modern BCM43xx devices Signed-off-by: Michael Buesch Signed-off-by: John W. Linville Signed-off-by: David S. Miller --- drivers/net/wireless/b43/pcmcia.c | 157 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 drivers/net/wireless/b43/pcmcia.c (limited to 'drivers/net/wireless/b43/pcmcia.c') diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c new file mode 100644 index 00000000000..3e75a8a12c9 --- /dev/null +++ b/drivers/net/wireless/b43/pcmcia.c @@ -0,0 +1,157 @@ +/* + + Broadcom B43 wireless driver + + Copyright (c) 2007 Michael Buesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include + +#include +#include +#include +#include +#include +#include + +static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = { + PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), + PCMCIA_DEVICE_NULL, +}; + +MODULE_DEVICE_TABLE(pcmcia, b43_pcmcia_tbl); + +#ifdef CONFIG_PM +static int b43_pcmcia_suspend(struct pcmcia_device *dev) +{ + //TODO + return 0; +} + +static int b43_pcmcia_resume(struct pcmcia_device *dev) +{ + //TODO + return 0; +} +#else /* CONFIG_PM */ +# define b43_pcmcia_suspend NULL +# define b43_pcmcia_resume NULL +#endif /* CONFIG_PM */ + +static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) +{ + struct ssb_bus *ssb; + win_req_t win; + memreq_t mem; + tuple_t tuple; + cisparse_t parse; + int err = -ENOMEM; + int res; + unsigned char buf[64]; + + ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); + if (!ssb) + goto out; + + err = -ENODEV; + tuple.DesiredTuple = CISTPL_CONFIG; + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + + res = pcmcia_get_first_tuple(dev, &tuple); + if (res != CS_SUCCESS) + goto err_kfree_ssb; + res = pcmcia_get_tuple_data(dev, &tuple); + if (res != CS_SUCCESS) + goto err_kfree_ssb; + res = pcmcia_parse_tuple(dev, &tuple, &parse); + if (res != CS_SUCCESS) + goto err_kfree_ssb; + + dev->conf.ConfigBase = parse.config.base; + dev->conf.Present = parse.config.rmask[0]; + + dev->io.BasePort2 = 0; + dev->io.NumPorts2 = 0; + dev->io.Attributes2 = 0; + + win.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; + win.Base = 0; + win.Size = SSB_CORE_SIZE; + win.AccessSpeed = 1000; + res = pcmcia_request_window(&dev, &win, &dev->win); + if (res != CS_SUCCESS) + goto err_kfree_ssb; + + mem.CardOffset = 0; + mem.Page = 0; + res = pcmcia_map_mem_page(dev->win, &mem); + if (res != CS_SUCCESS) + goto err_kfree_ssb; + + res = pcmcia_request_configuration(dev, &dev->conf); + if (res != CS_SUCCESS) + goto err_disable; + + err = ssb_bus_pcmciabus_register(ssb, dev, win.Base); + dev->priv = ssb; + + out: + return err; + err_disable: + pcmcia_disable_device(dev); + err_kfree_ssb: + kfree(ssb); + return err; +} + +static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev) +{ + struct ssb_bus *ssb = dev->priv; + + ssb_bus_unregister(ssb); + pcmcia_release_window(dev->win); + pcmcia_disable_device(dev); + kfree(ssb); + dev->priv = NULL; +} + +static struct pcmcia_driver b43_pcmcia_driver = { + .owner = THIS_MODULE, + .drv = { + .name = "b43-pcmcia", + }, + .id_table = b43_pcmcia_tbl, + .probe = b43_pcmcia_probe, + .remove = b43_pcmcia_remove, + .suspend = b43_pcmcia_suspend, + .resume = b43_pcmcia_resume, +}; + +int b43_pcmcia_init(void) +{ + return pcmcia_register_driver(&b43_pcmcia_driver); +} + +void b43_pcmcia_exit(void) +{ + pcmcia_unregister_driver(&b43_pcmcia_driver); +} -- cgit v1.2.3-70-g09d2 From 1a09404a2338163f181d170c7abdc2242b6c6f03 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 20 Sep 2007 11:13:40 -0700 Subject: [B43]: Fix sparse warnings. The remaining warning in phy.c will be fixed later. Signed-off-by: Michael Buesch Signed-off-by: David S. Miller --- drivers/net/wireless/b43/debugfs.c | 31 +++++++++++++++++++++---------- drivers/net/wireless/b43/leds.c | 8 ++++---- drivers/net/wireless/b43/leds.h | 8 ++++---- drivers/net/wireless/b43/main.c | 5 ++--- drivers/net/wireless/b43/pcmcia.c | 3 +++ drivers/net/wireless/b43/pio.c | 18 ++++++++++-------- drivers/net/wireless/b43/pio.h | 3 +-- drivers/net/wireless/b43/xmit.c | 8 +++++--- 8 files changed, 50 insertions(+), 34 deletions(-) (limited to 'drivers/net/wireless/b43/pcmcia.c') diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c index f82e3ef9bd7..3aafde9f08a 100644 --- a/drivers/net/wireless/b43/debugfs.c +++ b/drivers/net/wireless/b43/debugfs.c @@ -39,7 +39,7 @@ /* The root directory. */ -struct dentry *rootdir; +static struct dentry *rootdir; struct b43_debugfs_fops { ssize_t (*read)(struct b43_wldev *dev, char *buf, size_t bufsize); @@ -76,7 +76,8 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev, /* wl->irq_lock is locked */ -ssize_t tsf_read_file(struct b43_wldev *dev, char *buf, size_t bufsize) +static ssize_t tsf_read_file(struct b43_wldev *dev, + char *buf, size_t bufsize) { ssize_t count = 0; u64 tsf; @@ -90,7 +91,8 @@ ssize_t tsf_read_file(struct b43_wldev *dev, char *buf, size_t bufsize) } /* wl->irq_lock is locked */ -int tsf_write_file(struct b43_wldev *dev, const char *buf, size_t count) +static int tsf_write_file(struct b43_wldev *dev, + const char *buf, size_t count) { u64 tsf; @@ -102,7 +104,8 @@ int tsf_write_file(struct b43_wldev *dev, const char *buf, size_t count) } /* wl->irq_lock is locked */ -ssize_t ucode_regs_read_file(struct b43_wldev *dev, char *buf, size_t bufsize) +static ssize_t ucode_regs_read_file(struct b43_wldev *dev, + char *buf, size_t bufsize) { ssize_t count = 0; int i; @@ -116,7 +119,8 @@ ssize_t ucode_regs_read_file(struct b43_wldev *dev, char *buf, size_t bufsize) } /* wl->irq_lock is locked */ -ssize_t shm_read_file(struct b43_wldev *dev, char *buf, size_t bufsize) +static ssize_t shm_read_file(struct b43_wldev *dev, + char *buf, size_t bufsize) { ssize_t count = 0; int i; @@ -135,7 +139,8 @@ ssize_t shm_read_file(struct b43_wldev *dev, char *buf, size_t bufsize) return count; } -ssize_t txstat_read_file(struct b43_wldev *dev, char *buf, size_t bufsize) +static ssize_t txstat_read_file(struct b43_wldev *dev, + char *buf, size_t bufsize) { struct b43_txstatus_log *log = &dev->dfsentry->txstatlog; ssize_t count = 0; @@ -182,7 +187,8 @@ out_unlock: return count; } -ssize_t txpower_g_read_file(struct b43_wldev *dev, char *buf, size_t bufsize) +static ssize_t txpower_g_read_file(struct b43_wldev *dev, + char *buf, size_t bufsize) { ssize_t count = 0; @@ -214,7 +220,8 @@ out: return count; } -int txpower_g_write_file(struct b43_wldev *dev, const char *buf, size_t count) +static int txpower_g_write_file(struct b43_wldev *dev, + const char *buf, size_t count) { unsigned long flags; unsigned long phy_flags; @@ -262,7 +269,8 @@ out_unlock: } /* wl->irq_lock is locked */ -int restart_write_file(struct b43_wldev *dev, const char *buf, size_t count) +static int restart_write_file(struct b43_wldev *dev, + const char *buf, size_t count) { int err = 0; @@ -294,7 +302,8 @@ static ssize_t append_lo_table(ssize_t count, char *buf, const size_t bufsize, return count; } -ssize_t loctls_read_file(struct b43_wldev *dev, char *buf, size_t bufsize) +static ssize_t loctls_read_file(struct b43_wldev *dev, + char *buf, size_t bufsize) { ssize_t count = 0; struct b43_txpower_lo_control *lo; @@ -383,6 +392,8 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf, err = -ENOMEM; goto out_unlock; } + /* Sparse warns about the following memset, because it has a big + * size value. That warning is bogus, so I will ignore it. --mb */ memset(buf, 0, bufsize); if (dfops->take_irqlock) { spin_lock_irq(&dev->wl->irq_lock); diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 535f960412d..85d965de579 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c @@ -32,14 +32,13 @@ static void b43_led_changestate(struct b43_led *led) { struct b43_wldev *dev = led->dev; - const int index = b43_led_index(led); - const u16 mask = (1 << index); + const int index = led->index; u16 ledctl; B43_WARN_ON(!(index >= 0 && index < B43_NR_LEDS)); B43_WARN_ON(!led->blink_interval); ledctl = b43_read16(dev, B43_MMIO_GPIO_CONTROL); - ledctl = (ledctl & mask) ? (ledctl & ~mask) : (ledctl | mask); + ledctl ^= (1 << index); b43_write16(dev, B43_MMIO_GPIO_CONTROL, ledctl); } @@ -70,7 +69,7 @@ static void b43_led_blink_start(struct b43_led *led, unsigned long interval) static void b43_led_blink_stop(struct b43_led *led, int sync) { struct b43_wldev *dev = led->dev; - const int index = b43_led_index(led); + const int index = led->index; u16 ledctl; if (!led->blink_interval) @@ -139,6 +138,7 @@ int b43_leds_init(struct b43_wldev *dev) for (i = 0; i < B43_NR_LEDS; i++) { led = &(dev->leds[i]); + led->index = i; led->dev = dev; setup_timer(&led->blink_timer, b43_led_blink, (unsigned long)led); diff --git a/drivers/net/wireless/b43/leds.h b/drivers/net/wireless/b43/leds.h index 36b46cfda22..d94851d291c 100644 --- a/drivers/net/wireless/b43/leds.h +++ b/drivers/net/wireless/b43/leds.h @@ -5,14 +5,14 @@ #include struct b43_led { - u8 behaviour:7; - u8 activelow:1; - + u8 behaviour; + bool activelow; + /* Index in the "leds" array in b43_wldev */ + u8 index; struct b43_wldev *dev; struct timer_list blink_timer; unsigned long blink_interval; }; -#define b43_led_index(led) ((int)((led) - (led)->dev->leds)) /* Delay between state changes when blinking in jiffies */ #define B43_LEDBLINK_SLOW (HZ / 1) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index fd4ef27fcf2..66c89df51fb 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1062,7 +1062,7 @@ static void handle_irq_noise(struct b43_wldev *dev) B43_WARN_ON(!dev->noisecalc.calculation_running); if (dev->noisecalc.channel_at_start != phy->channel) goto drop_calculation; - *((u32 *) noise) = cpu_to_le32(b43_jssi_read(dev)); + *((__le32 *)noise) = cpu_to_le32(b43_jssi_read(dev)); if (noise[0] == 0x7F || noise[1] == 0x7F || noise[2] == 0x7F || noise[3] == 0x7F) goto generate_new; @@ -1598,8 +1598,7 @@ static int do_request_fw(struct b43_wldev *dev, const char *name, const struct firmware **fw) { - const size_t plen = sizeof(modparam_fwpostfix) + 32; - char path[plen]; + char path[sizeof(modparam_fwpostfix) + 32]; struct b43_fw_header *hdr; u32 size; int err; diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 3e75a8a12c9..b242a9a90dd 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -21,6 +21,8 @@ */ +#include "pcmcia.h" + #include #include @@ -30,6 +32,7 @@ #include #include + static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = { PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), PCMCIA_DEVICE_NULL, diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 4ac91fdd356..67752a28eb9 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c @@ -60,7 +60,7 @@ static u16 tx_get_next_word(const u8 * txhdr, source = packet; i -= txhdr_size; } - ret = le16_to_cpu(*((u16 *) (source + i))); + ret = le16_to_cpu(*((__le16 *)(source + i))); *pos += 2; return ret; @@ -104,7 +104,7 @@ static u16 generate_cookie(struct b43_pioqueue *queue, struct b43_pio_txpacket *packet) { u16 cookie = 0x0000; - int packetindex; + u16 packetindex; /* We use the upper 4 bits for the PIO * controller ID and the lower 12 bits @@ -125,7 +125,7 @@ static u16 generate_cookie(struct b43_pioqueue *queue, default: B43_WARN_ON(1); } - packetindex = pio_txpacket_getindex(packet); + packetindex = packet->index; B43_WARN_ON(packetindex & ~0x0FFF); cookie |= (u16) packetindex; @@ -286,6 +286,7 @@ static void setup_txqueues(struct b43_pioqueue *queue) packet->queue = queue; INIT_LIST_HEAD(&packet->list); + packet->index = i; list_add(&packet->list, &queue->txfree); } @@ -518,9 +519,10 @@ static void pio_rx_error(struct b43_pioqueue *queue, void b43_pio_rx(struct b43_pioqueue *queue) { - u16 preamble[21] = { 0 }; + __le16 preamble[21] = { 0 }; struct b43_rxhdr_fw4 *rxhdr; - u16 tmp, len, macstat; + u16 tmp, len; + u32 macstat; int i, preamble_readwords; struct sk_buff *skb; @@ -537,7 +539,7 @@ void b43_pio_rx(struct b43_pioqueue *queue) } b43dbg(queue->dev->wl, "PIO RX timed out\n"); return; - data_ready: +data_ready: len = b43_pio_read(queue, B43_PIO_RXDATA); if (unlikely(len > 0x700)) { @@ -558,7 +560,7 @@ void b43_pio_rx(struct b43_pioqueue *queue) preamble[i + 1] = cpu_to_le16(tmp); } rxhdr = (struct b43_rxhdr_fw4 *)preamble; - macstat = le16_to_cpu(rxhdr->mac_status); + macstat = le32_to_cpu(rxhdr->mac_status); if (macstat & B43_RX_MAC_FCSERR) { pio_rx_error(queue, (queue->mmio_base == B43_MMIO_PIO1_BASE), @@ -583,7 +585,7 @@ void b43_pio_rx(struct b43_pioqueue *queue) skb_put(skb, len); for (i = 0; i < len - 1; i += 2) { tmp = b43_pio_read(queue, B43_PIO_RXDATA); - *((u16 *) (skb->data + i)) = cpu_to_le16(tmp); + *((__le16 *)(skb->data + i)) = cpu_to_le16(tmp); } if (len % 2) { tmp = b43_pio_read(queue, B43_PIO_RXDATA); diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h index 46d6d2ea9b5..34a44c1b631 100644 --- a/drivers/net/wireless/b43/pio.h +++ b/drivers/net/wireless/b43/pio.h @@ -39,10 +39,9 @@ struct b43_pio_txpacket { struct sk_buff *skb; struct ieee80211_tx_status txstat; struct list_head list; + u16 index; /* Index in the tx_packets_cache */ }; -#define pio_txpacket_getindex(packet) ((int)((packet) - (packet)->queue->tx_packets_cache)) - struct b43_pioqueue { struct b43_wldev *dev; u16 mmio_base; diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index e6174b6f11f..0bd6f8a348a 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -121,10 +121,12 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, __u8 *raw = plcp->raw; if (b43_is_ofdm_rate(bitrate)) { - *data = b43_plcp_get_ratecode_ofdm(bitrate); + u32 d; + + d = b43_plcp_get_ratecode_ofdm(bitrate); B43_WARN_ON(octets & 0xF000); - *data |= (octets << 5); - *data = cpu_to_le32(*data); + d |= (octets << 5); + *data = cpu_to_le32(d); } else { u32 plen; -- cgit v1.2.3-70-g09d2