Commit f222313a authored by John W. Linville's avatar John W. Linville

[PATCH] wireless: import bcm43xx sources

Import the bcm43xx driver from the upstream sources here:

ftp://ftp.berlios.de/pub/bcm43xx/snapshots/bcm43xx/bcm43xx-20060123.tar.bz2Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5d5d7727
This diff is collapsed.
# Makefile for bcm43xx driver
VERSION := 0.0.1
RELEASE_NAME := bcm43xx-$(VERSION)
# Optional path, where the SoftMAC subsystem is located.
# You may set SOFTMAC_DIR in your bashrc, for example.
SOFTMAC_DIR ?=
KVER := $(shell uname -r)
KDIR ?= /lib/modules/$(KVER)/build
PWD := $(shell pwd)
MODPATH := $(DESTDIR)/lib/modules/$(KVER)/kernel/drivers/net/bcm43xx
# Comment/uncomment to enable/disable debugging
DEBUG = y
ifeq ($(DEBUG),y)
DEBUGFS_OBJ = bcm43xx_debugfs.o
CFLAGS += -O2 -DCONFIG_BCM43XX_DEBUG
else
DEBUGFS_OBJ =
CFLAGS += -O2
endif
CFLAGS += -DBCM43xx_VERSION=$(VERSION) -I/lib/modules/$(KVER)/include
ifneq ($(SOFTMAC_DIR),)
CPPFLAGS := -I$(SOFTMAC_DIR) $(CPPFLAGS)
endif
ifneq ($(KERNELRELEASE),)
# call from kernel build system
obj-m := bcm43xx.o
bcm43xx-objs := bcm43xx_main.o bcm43xx_dma.o $(DEBUGFS_OBJ) \
bcm43xx_radio.o bcm43xx_phy.o \
bcm43xx_power.o bcm43xx_wx.o \
bcm43xx_pio.o bcm43xx_ilt.o \
bcm43xx_leds.o
else
default: modules
modules:
$(MAKE) -C $(KDIR) M=$(PWD) modules
install: bcm43xx.ko
install -d $(MODPATH)
install -m 644 -c bcm43xx.ko $(MODPATH)
/sbin/depmod -a
uninstall:
rm -rf $(MODPATH)
/sbin/depmod -a
endif
clean:
find . \( -name '*.ko' -o -name '*.o' -o -name '.tmp_versions' -o -name '*~' -o -name '.*.cmd' \
-o -name '*.mod.c' -o -name '*.tar.bz2' -o -name '*.rej' -o -name '*.orig' \)\
-print | xargs rm -Rf
depend .depend dep:
$(CC) $(CFLAGS) -M *.c > .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif
DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v "\.tar\.bz2" | grep -v "\/\." )
DISTDIR = $(RELEASE_NAME)
release: clean
@rm -rf $(DISTDIR)
@mkdir $(DISTDIR)
@chmod 777 $(DISTDIR)
@for file in $(DISTFILES); do \
if test -d $$file; then \
mkdir $(DISTDIR)/$$file; \
else \
cp -p $$file $(DISTDIR)/$$file; \
fi; \
done
@tar -c $(DISTDIR) | bzip2 -9 > $(RELEASE_NAME).tar.bz2
@rm -rf $(DISTDIR)
BCM43xx Linux Driver Project
============================
About this software
-------------------
The goal of this project is to develop a linux driver for Broadcom
BCM43xx chips, based on the specification at
http://bcm-specs.sipsolutions.net/
The project page is http://bcm43xx.berlios.de/
Requirements
------------
1) Linux Kernel 2.6.15 or later
http://www.kernel.org/
You may want to configure your kernel with:
CONFIG_DEBUG_FS (optional):
-> Kernel hacking
-> Debug Filesystem
2) SoftMAC IEEE 802.11 Networking Stack extension and patched ieee80211
modules:
http://softmac.sipsolutions.net/
3) Firmware Files
Please try fwcutter. Fwcutter can extract the firmware from various
binary driver files. It supports driver files from Windows, MacOS and
Linux. You can get fwcutter from http://bcm43xx.berlios.de/.
Also, fwcutter comes with a README file for further instructions.
This diff is collapsed.
This diff is collapsed.
#ifndef BCM43xx_DEBUGFS_H_
#define BCM43xx_DEBUGFS_H_
struct bcm43xx_private;
struct bcm43xx_xmitstatus;
#ifdef CONFIG_BCM43XX_DEBUG
#include <linux/list.h>
#include <asm/semaphore.h>
struct dentry;
/* limited by the size of the "really_big_buffer" */
#define BCM43xx_NR_LOGGED_XMITSTATUS 100
struct bcm43xx_dfsentry {
struct dentry *subdir;
struct dentry *dentry_devinfo;
struct dentry *dentry_spromdump;
struct dentry *dentry_tsf;
struct dentry *dentry_txstat;
struct bcm43xx_private *bcm;
/* saved xmitstatus. */
struct bcm43xx_xmitstatus *xmitstatus_buffer;
int xmitstatus_ptr;
int xmitstatus_cnt;
/* We need a seperate buffer while printing to avoid
* concurrency issues. (New xmitstatus can arrive
* while we are printing).
*/
struct bcm43xx_xmitstatus *xmitstatus_print_buffer;
int saved_xmitstatus_ptr;
int saved_xmitstatus_cnt;
int xmitstatus_printing;
};
struct bcm43xx_debugfs {
struct dentry *root;
struct dentry *dentry_driverinfo;
};
void bcm43xx_debugfs_init(void);
void bcm43xx_debugfs_exit(void);
void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm);
void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm);
void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status);
/* Debug helper: Dump binary data through printk. */
void bcm43xx_printk_dump(const char *data,
size_t size,
const char *description);
/* Debug helper: Dump bitwise binary data through printk. */
void bcm43xx_printk_bitdump(const unsigned char *data,
size_t bytes, int msb_to_lsb,
const char *description);
#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \
do { \
bcm43xx_printk_bitdump((const unsigned char *)(pointer), \
sizeof(*(pointer)), \
(msb_to_lsb), \
(description)); \
} while (0)
#else /* CONFIG_BCM43XX_DEBUG*/
static inline
void bcm43xx_debugfs_init(void) { }
static inline
void bcm43xx_debugfs_exit(void) { }
static inline
void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) { }
static inline
void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) { }
static inline
void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status) { }
static inline
void bcm43xx_printk_dump(const char *data,
size_t size,
const char *description)
{
}
static inline
void bcm43xx_printk_bitdump(const unsigned char *data,
size_t bytes, int msb_to_lsb,
const char *description)
{
}
#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0)
#endif /* CONFIG_BCM43XX_DEBUG*/
/* Ugly helper macros to make incomplete code more verbose on runtime */
#ifdef TODO
# undef TODO
#endif
#define TODO() \
do { \
printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \
__FUNCTION__, __FILE__, __LINE__); \
} while (0)
#ifdef FIXME
# undef FIXME
#endif
#define FIXME() \
do { \
printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \
__FUNCTION__, __FILE__, __LINE__); \
} while (0)
#endif /* BCM43xx_DEBUGFS_H_ */
This diff is collapsed.
#ifndef BCM43xx_DMA_H_
#define BCM43xx_DMA_H_
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/linkage.h>
#include <asm/atomic.h>
/* DMA-Interrupt reasons. */
/*TODO: add the missing ones. */
#define BCM43xx_DMAIRQ_ERR0 (1 << 10)
#define BCM43xx_DMAIRQ_ERR1 (1 << 11)
#define BCM43xx_DMAIRQ_ERR2 (1 << 12)
#define BCM43xx_DMAIRQ_ERR3 (1 << 13)
#define BCM43xx_DMAIRQ_ERR4 (1 << 14)
#define BCM43xx_DMAIRQ_ERR5 (1 << 15)
#define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
/* helpers */
#define BCM43xx_DMAIRQ_ANYERR (BCM43xx_DMAIRQ_ERR0 | \
BCM43xx_DMAIRQ_ERR1 | \
BCM43xx_DMAIRQ_ERR2 | \
BCM43xx_DMAIRQ_ERR3 | \
BCM43xx_DMAIRQ_ERR4 | \
BCM43xx_DMAIRQ_ERR5)
#define BCM43xx_DMAIRQ_FATALERR (BCM43xx_DMAIRQ_ERR0 | \
BCM43xx_DMAIRQ_ERR1 | \
BCM43xx_DMAIRQ_ERR2 | \
BCM43xx_DMAIRQ_ERR4 | \
BCM43xx_DMAIRQ_ERR5)
#define BCM43xx_DMAIRQ_NONFATALERR BCM43xx_DMAIRQ_ERR3
/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
#define BCM43xx_DMA_TX_CONTROL 0x00
#define BCM43xx_DMA_TX_DESC_RING 0x04
#define BCM43xx_DMA_TX_DESC_INDEX 0x08
#define BCM43xx_DMA_TX_STATUS 0x0c
#define BCM43xx_DMA_RX_CONTROL 0x10
#define BCM43xx_DMA_RX_DESC_RING 0x14
#define BCM43xx_DMA_RX_DESC_INDEX 0x18
#define BCM43xx_DMA_RX_STATUS 0x1c
/* DMA controller channel control word values. */
#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0)
#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1)
#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2)
#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4)
#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0)
#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe
#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1
#define BCM43xx_DMA_RXCTRL_PIO (1 << 8)
/* DMA controller channel status word values. */
#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff
#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000
#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000
#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000
#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000
#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000
#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000
#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000
#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20)
#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff
#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000
#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000
#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000
#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000
#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000
#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000
#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000
/* DMA descriptor control field values. */
#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff
#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor table */
#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on completion request */
#define BCM43xx_DMADTOR_FRAMEEND (1 << 30)
#define BCM43xx_DMADTOR_FRAMESTART (1 << 31)
/* Misc DMA constants */
#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE
#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF
#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30)
#define BCM43xx_DMA1_RX_FRAMEOFFSET 30
#define BCM43xx_DMA4_RX_FRAMEOFFSET 0
/* DMA engine tuning knobs */
#define BCM43xx_TXRING_SLOTS 512
#define BCM43xx_RXRING_SLOTS 64
#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100)
#define BCM43xx_DMA4_RXBUFFERSIZE 16
/* Suspend the tx queue, if less than this percent slots are free. */
#define BCM43xx_TXSUSPEND_PERCENT 20
/* Resume the tx queue, if more than this percent slots are free. */
#define BCM43xx_TXRESUME_PERCENT 50
struct sk_buff;
struct bcm43xx_private;
struct bcm43xx_xmitstatus;
struct bcm43xx_dmadesc {
__le32 _control;
__le32 _address;
} __attribute__((__packed__));
/* Macros to access the bcm43xx_dmadesc struct */
#define get_desc_ctl(desc) le32_to_cpu((desc)->_control)
#define set_desc_ctl(desc, ctl) do { (desc)->_control = cpu_to_le32(ctl); } while (0)
#define get_desc_addr(desc) le32_to_cpu((desc)->_address)
#define set_desc_addr(desc, addr) do { (desc)->_address = cpu_to_le32(addr); } while (0)
struct bcm43xx_dmadesc_meta {
/* The kernel DMA-able buffer. */
struct sk_buff *skb;
/* DMA base bus-address of the descriptor buffer. */
dma_addr_t dmaaddr;
/* Pointer to our txb (can be NULL).
* This should be freed in completion IRQ.
*/
struct ieee80211_txb *txb;
};
struct bcm43xx_dmaring {
spinlock_t lock;
struct bcm43xx_private *bcm;
/* Kernel virtual base address of the ring memory. */
struct bcm43xx_dmadesc *vbase;
/* DMA memory offset */
dma_addr_t memoffset;
/* (Unadjusted) DMA base bus-address of the ring memory. */
dma_addr_t dmabase;
/* Meta data about all descriptors. */
struct bcm43xx_dmadesc_meta *meta;
/* Number of descriptor slots in the ring. */
int nr_slots;
/* Number of used descriptor slots. */
int used_slots;
/* Currently used slot in the ring. */
int current_slot;
/* Marks to suspend/resume the queue. */
int suspend_mark;
int resume_mark;
/* Frameoffset in octets. */
u32 frameoffset;
/* Descriptor buffer size. */
u16 rx_buffersize;
/* The MMIO base register of the DMA controller, this
* ring is posted to.
*/
u16 mmio_base;
u8 tx:1, /* TRUE, if this is a TX ring. */
suspended:1; /* TRUE, if transfers are suspended on this ring. */
#ifdef CONFIG_BCM43XX_DEBUG
/* Maximum number of used slots. */
int max_used_slots;
#endif /* CONFIG_BCM43XX_DEBUG*/
};
int bcm43xx_dma_init(struct bcm43xx_private *bcm);
void bcm43xx_dma_free(struct bcm43xx_private *bcm);
int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
u16 dmacontroller_mmio_base);
int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
u16 dmacontroller_mmio_base);
int FASTCALL(bcm43xx_dma_transfer_txb(struct bcm43xx_private *bcm,
struct ieee80211_txb *txb));
void FASTCALL(bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status));
void FASTCALL(bcm43xx_dma_rx(struct bcm43xx_dmaring *ring));
#endif /* BCM43xx_DMA_H_ */
This diff is collapsed.
#ifndef BCM43xx_ILT_H_
#define BCM43xx_ILT_H_
#define BCM43xx_ILT_ROTOR_SIZE 53
extern const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE];
#define BCM43xx_ILT_RETARD_SIZE 53
extern const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE];
#define BCM43xx_ILT_FINEFREQA_SIZE 256
extern const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE];
#define BCM43xx_ILT_FINEFREQG_SIZE 256
extern const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE];
#define BCM43xx_ILT_NOISEA2_SIZE 8
extern const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE];
#define BCM43xx_ILT_NOISEA3_SIZE 8
extern const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE];
#define BCM43xx_ILT_NOISEG1_SIZE 8
extern const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE];
#define BCM43xx_ILT_NOISEG2_SIZE 8
extern const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE];
#define BCM43xx_ILT_NOISESCALEG_SIZE 27
extern const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE];
extern const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE];
extern const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE];
#define BCM43xx_ILT_SIGMASQR_SIZE 53
extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE];
extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE];
void bcm43xx_ilt_write16(struct bcm43xx_private *bcm, u16 offset, u16 val);
u16 bcm43xx_ilt_read16(struct bcm43xx_private *bcm, u16 offset);
void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val);
u32 bcm43xx_ilt_read32(struct bcm43xx_private *bcm, u16 offset);
#endif /* BCM43xx_ILT_H_ */
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
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 "bcm43xx_leds.h"
#include "bcm43xx.h"
#include <asm/bitops.h>
static void bcm43xx_led_changestate(struct bcm43xx_led *led)
{
struct bcm43xx_private *bcm = led->bcm;
const int index = bcm43xx_led_index(led);
u16 ledctl;
assert(index >= 0 && index < BCM43xx_NR_LEDS);
assert(led->blink_interval);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
__change_bit(index, (unsigned long *)(&ledctl));
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
}
static void bcm43xx_led_blink(unsigned long d)
{
struct bcm43xx_led *led = (struct bcm43xx_led *)d;
struct bcm43xx_private *bcm = led->bcm;
unsigned long flags;
spin_lock_irqsave(&bcm->lock, flags);
if (led->blink_interval) {
bcm43xx_led_changestate(led);
mod_timer(&led->blink_timer, jiffies + led->blink_interval);
}
spin_unlock_irqrestore(&bcm->lock, flags);
}
static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
unsigned long interval)
{
led->blink_interval = interval;
bcm43xx_led_changestate(led);
led->blink_timer.expires = jiffies + interval;
add_timer(&led->blink_timer);
}
static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync)
{
struct bcm43xx_private *bcm = led->bcm;
const int index = bcm43xx_led_index(led);
u16 ledctl;
if (!led->blink_interval)
return;
if (unlikely(sync))
del_timer_sync(&led->blink_timer);
else
del_timer(&led->blink_timer);
led->blink_interval = 0;
/* Make sure the LED is turned off. */
assert(index >= 0 && index < BCM43xx_NR_LEDS);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
if (led->activelow)
ledctl |= (1 << index);
else
ledctl &= ~(1 << index);
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
}
int bcm43xx_leds_init(struct bcm43xx_private *bcm)
{
struct bcm43xx_led *led;
u8 sprom[4];
int i;
sprom[0] = bcm->sprom.wl0gpio0;
sprom[1] = bcm->sprom.wl0gpio1;
sprom[2] = bcm->sprom.wl0gpio2;
sprom[3] = bcm->sprom.wl0gpio3;
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
led->bcm = bcm;
init_timer(&led->blink_timer);
led->blink_timer.data = (unsigned long)led;
led->blink_timer.function = bcm43xx_led_blink;
if (sprom[i] == 0xFF) {
/* SPROM information not set. */
switch (i) {
case 0:
if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
led->behaviour = BCM43xx_LED_RADIO_ALL;
else
led->behaviour = BCM43xx_LED_ACTIVITY;
break;
case 1:
led->behaviour = BCM43xx_LED_RADIO_B;
break;
case 2:
led->behaviour = BCM43xx_LED_RADIO_A;
break;
case 3:
led->behaviour = BCM43xx_LED_OFF;
break;
default:
assert(0);
}
} else {
led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR;
led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW);
}
}
return 0;
}
void bcm43xx_leds_exit(struct bcm43xx_private *bcm)
{
struct bcm43xx_led *led;
int i;
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
bcm43xx_led_blink_stop(led, 1);
}
bcm43xx_leds_turn_off(bcm);
}
void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
{
struct bcm43xx_led *led;
struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES;
int i, turn_on = 0;
unsigned long interval = 0;
u16 ledctl;
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
if (led->behaviour == BCM43xx_LED_INACTIVE)
continue;
switch (led->behaviour) {
case BCM43xx_LED_OFF:
turn_on = 0;
break;
case BCM43xx_LED_ON:
turn_on = 1;
break;
case BCM43xx_LED_ACTIVITY:
turn_on = activity;
break;
case BCM43xx_LED_RADIO_ALL:
turn_on = radio->enabled;
break;
case BCM43xx_LED_RADIO_A:
turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A);
break;
case BCM43xx_LED_RADIO_B:
turn_on = (radio->enabled &&
(phy->type == BCM43xx_PHYTYPE_B ||
phy->type == BCM43xx_PHYTYPE_G));
break;
case BCM43xx_LED_MODE_BG:
turn_on = 0;
if (phy->type == BCM43xx_PHYTYPE_G &&
1/*FIXME: using G rates.*/)
turn_on = 1;
break;
case BCM43xx_LED_TRANSFER:
if (transferring)
bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM);
else
bcm43xx_led_blink_stop(led, 0);
continue;
case BCM43xx_LED_APTRANSFER:
if (bcm->ieee->iw_mode == IW_MODE_MASTER) {
if (transferring) {
interval = BCM43xx_LEDBLINK_FAST;
turn_on = 1;
}
} else {
turn_on = 1;
if (0/*TODO: not assoc*/)
interval = BCM43xx_LEDBLINK_SLOW;
else if (transferring)
interval = BCM43xx_LEDBLINK_FAST;
else
turn_on = 0;
}
if (turn_on)
bcm43xx_led_blink_start(led, interval);
else
bcm43xx_led_blink_stop(led, 0);
continue;
case BCM43xx_LED_WEIRD:
//TODO
turn_on = 0;
break;
case BCM43xx_LED_ASSOC:
if (1/*TODO: associated*/)
turn_on = 1;
break;
default:
assert(0);
};
if (led->activelow)
turn_on = !turn_on;
if (turn_on)
ledctl |= (1 << i);
else
ledctl &= ~(1 << i);
}
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
}
void bcm43xx_leds_turn_off(struct bcm43xx_private *bcm)
{
struct bcm43xx_led *led;
u16 ledctl = 0;
int i;
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
if (led->behaviour == BCM43xx_LED_INACTIVE)
continue;
if (led->activelow)
ledctl |= (1 << i);
}
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
}
/* vim: set ts=8 sw=8 sts=8: */
#ifndef BCM43xx_LEDS_H_
#define BCM43xx_LEDS_H_
#include <linux/types.h>
#include <linux/timer.h>
struct bcm43xx_led {
u8 behaviour:7;
u8 activelow:1;
struct bcm43xx_private *bcm;
struct timer_list blink_timer;
unsigned long blink_interval;
};
#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds))
/* Delay between state changes when blinking in jiffies */
#define BCM43xx_LEDBLINK_SLOW (HZ / 2)
#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4)
#define BCM43xx_LEDBLINK_FAST (HZ / 8)
#define BCM43xx_LED_XFER_THRES (HZ / 100)
#define BCM43xx_LED_BEHAVIOUR 0x7F
#define BCM43xx_LED_ACTIVELOW 0x80
enum { /* LED behaviour values */
BCM43xx_LED_OFF,
BCM43xx_LED_ON,
BCM43xx_LED_ACTIVITY,
BCM43xx_LED_RADIO_ALL,
BCM43xx_LED_RADIO_A,
BCM43xx_LED_RADIO_B,
BCM43xx_LED_MODE_BG,
BCM43xx_LED_TRANSFER,
BCM43xx_LED_APTRANSFER,
BCM43xx_LED_WEIRD,//FIXME
BCM43xx_LED_ASSOC,
BCM43xx_LED_INACTIVE,
};
int bcm43xx_leds_init(struct bcm43xx_private *bcm);
void bcm43xx_leds_exit(struct bcm43xx_private *bcm);
void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity);
void bcm43xx_leds_turn_off(struct bcm43xx_private *bcm);
#endif /* BCM43xx_LEDS_H_ */
This diff is collapsed.
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
Some parts of the code in this file are derived from the ipw2200
driver Copyright(c) 2003 - 2004 Intel Corporation.
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.
*/
#ifndef BCM43xx_MAIN_H_
#define BCM43xx_MAIN_H_
#include "bcm43xx.h"
#ifdef CONFIG_BCM947XX
#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
static inline void e_aton(char *str, char *dest)
{
int i = 0;
u16 *d = (u16 *) dest;
for (;;) {
dest[i++] = (char) simple_strtoul(str, NULL, 16);
str += 2;
if (!*str++ || i == 6)
break;
}
for (i = 0; i < 3; i++)
d[i] = cpu_to_be16(d[i]);
}
#endif
#define _bcm43xx_declare_plcp_hdr(size) \
struct bcm43xx_plcp_hdr##size { \
union { \
__le32 data; \
__u8 raw[size]; \
} __attribute__((__packed__)); \
} __attribute__((__packed__))
/* struct bcm43xx_plcp_hdr4 */
_bcm43xx_declare_plcp_hdr(4);
/* struct bcm430c_plcp_hdr6 */
_bcm43xx_declare_plcp_hdr(6);
#undef _bcm43xx_declare_plcp_hdr
#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes]
#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes)
/* Magic helper macro to pad structures. Ignore those above. It's magic. */
#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes))
/* Device specific TX header. To be prepended to TX frames. */
struct bcm43xx_txhdr {
union {
struct {
u16 flags;
u16 wsec_rate;
u16 frame_control;
u16 unknown_zeroed_0;
u16 control;
unsigned char wep_iv[10];
unsigned char unknown_wsec_tkip_data[3]; //FIXME
PAD_BYTES(3);
unsigned char mac1[6];
u16 unknown_zeroed_1;
struct bcm43xx_plcp_hdr4 rts_cts_fallback_plcp;
u16 rts_cts_dur_fallback;
struct bcm43xx_plcp_hdr4 fallback_plcp;
u16 fallback_dur_id;
PAD_BYTES(2);
u16 cookie;
u16 unknown_scb_stuff; //FIXME
struct bcm43xx_plcp_hdr6 rts_cts_plcp;
u16 rts_cts_frame_type;
u16 rts_cts_dur;
unsigned char rts_cts_mac1[6];
unsigned char rts_cts_mac2[6];
PAD_BYTES(2);
struct bcm43xx_plcp_hdr6 plcp;
} __attribute__((__packed__));
unsigned char raw[82];
} __attribute__((__packed__));
} __attribute__((__packed__));
struct sk_buff;
void FASTCALL(bcm43xx_generate_txhdr(struct bcm43xx_private *bcm,
struct bcm43xx_txhdr *txhdr,
const unsigned char *fragment_data,
const unsigned int fragment_len,
const int is_first_fragment,
const u16 cookie));
/* RX header as received from the hardware. */
struct bcm43xx_rxhdr {
/* Frame Length. Must be generated explicitely in PIO mode. */
__le16 frame_length;
PAD_BYTES(2);
/* Flags field 1 */
__le16 flags1;
u8 rssi;
u8 signal_quality;
PAD_BYTES(2);
/* Flags field 3 */
__le16 flags3;
/* Flags field 2 */
__le16 flags2;
/* Lower 16bits of the TSF at the time the frame started. */
__le16 mactime;
PAD_BYTES(14);
} __attribute__((__packed__));
#define BCM43xx_RXHDR_FLAGS1_OFDM (1 << 0)
/*#define BCM43xx_RXHDR_FLAGS1_SIGNAL??? (1 << 3) FIXME */
#define BCM43xx_RXHDR_FLAGS1_SHORTPREAMBLE (1 << 7)
#define BCM43xx_RXHDR_FLAGS1_2053RSSIADJ (1 << 14)
#define BCM43xx_RXHDR_FLAGS2_INVALIDFRAME (1 << 0)
#define BCM43xx_RXHDR_FLAGS2_TYPE2FRAME (1 << 2)
/*FIXME: WEP related flags */
#define BCM43xx_RXHDR_FLAGS3_2050RSSIADJ (1 << 10)
/* Transmit Status as received from the hardware. */
struct bcm43xx_hwxmitstatus {
PAD_BYTES(4);
__le16 cookie;
u8 flags;
u8 cnt1:4,
cnt2:4;
PAD_BYTES(2);
__le16 seq;
__le16 unknown; //FIXME
} __attribute__((__packed__));
/* Transmit Status in CPU byteorder. */
struct bcm43xx_xmitstatus {
u16 cookie;
u8 flags;
u8 cnt1:4,
cnt2:4;
u16 seq;
u16 unknown; //FIXME
};
#define BCM43xx_TXSTAT_FLAG_ACK 0x01
//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x02
//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x04
//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x08
//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x10
#define BCM43xx_TXSTAT_FLAG_IGNORE 0x20
//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x40
//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x80
struct bcm43xx_xmitstatus_queue {
struct list_head list;
struct bcm43xx_hwxmitstatus status;
};
/* Lightweight function to convert a frequency (in Mhz) to a channel number. */
static inline
u8 bcm43xx_freq_to_channel(struct bcm43xx_private *bcm,
int freq)
{
u8 channel;
if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A) {
channel = (freq - 5000) / 5;
} else {
if (freq == 2484)
channel = 14;
else
channel = (freq - 2407) / 5;
}
return channel;
}
/* Lightweight function to convert a channel number to a frequency (in Mhz). */
static inline
int bcm43xx_channel_to_freq(struct bcm43xx_private *bcm,
u8 channel)
{
int freq;
if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A) {
freq = 5000 + (5 * channel);
} else {
if (channel == 14)
freq = 2484;
else
freq = 2407 + (5 * channel);
}
return freq;
}
/* Lightweight function to check if a channel number is valid.
* Note that this does _NOT_ check for geographical restrictions!
*/
static inline
int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm,
u8 channel)
{
if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A) {
if (channel <= 200)
return 1;
} else {
if (channel >= 1 && channel <= 14)
return 1;
}
return 0;
}
void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf);
void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf);
int FASTCALL(bcm43xx_rx(struct bcm43xx_private *bcm,
struct sk_buff *skb,
struct bcm43xx_rxhdr *rxhdr));
void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
int iw_mode);
u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm,
u16 routing, u16 offset);
u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm,
u16 routing, u16 offset);
void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
u16 routing, u16 offset,
u32 value);
void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
u16 routing, u16 offset,
u16 value);
void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm);
int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core);
void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
int bcm43xx_pci_read_config_16(struct pci_dev *pdev, u16 offset, u16 *val);
int bcm43xx_pci_read_config_32(struct pci_dev *pdev, u16 offset, u32 *val);
int bcm43xx_pci_write_config_16(struct pci_dev *pdev, int offset, u16 val);
int bcm43xx_pci_write_config_32(struct pci_dev *pdev, int offset, u32 val);
void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
void bcm43xx_mac_enable(struct bcm43xx_private *bcm);
u8 bcm43xx_sprom_crc(const u16 *sprom);
void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason);
#endif /* BCM43xx_MAIN_H_ */
This diff is collapsed.
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
Some parts of the code in this file are derived from the ipw2200
driver Copyright(c) 2003 - 2004 Intel Corporation.
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.
*/
#ifndef BCM43xx_PHY_H_
#define BCM43xx_PHY_H_
#include <linux/types.h>
struct bcm43xx_private;
void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm);
#define bcm43xx_phy_lock(bcm, flags) \
do { \
local_irq_save(flags); \
bcm43xx_raw_phy_lock(bcm); \
} while (0)
void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm);
#define bcm43xx_phy_unlock(bcm, flags) \
do { \
bcm43xx_raw_phy_unlock(bcm); \
local_irq_restore(flags); \
} while (0)
u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset);
void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm);
int bcm43xx_phy_init(struct bcm43xx_private *bcm);
void bcm43xx_phy_set_antenna_diversity(struct bcm43xx_private *bcm);
void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm);
int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect);
void bcm43xx_phy_lo_b_measure(struct bcm43xx_private *bcm);
void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm);
void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm);
/* Adjust the LocalOscillator to the saved values.
* "fixed" is only set to 1 once in initialization. Set to 0 otherwise.
*/
void bcm43xx_phy_lo_adjust(struct bcm43xx_private *bcm, int fixed);
void bcm43xx_phy_lo_mark_all_unused(struct bcm43xx_private *bcm);
void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
u16 baseband_attenuation);
#endif /* BCM43xx_PHY_H_ */
This diff is collapsed.
#ifndef BCM43xx_PIO_H_
#define BCM43xx_PIO_H_
#include "bcm43xx.h"
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/skbuff.h>
#define BCM43xx_PIO_TXCTL 0x00
#define BCM43xx_PIO_TXDATA 0x02
#define BCM43xx_PIO_TXQBUFSIZE 0x04
#define BCM43xx_PIO_RXCTL 0x08
#define BCM43xx_PIO_RXDATA 0x0A
#define BCM43xx_PIO_TXCTL_WRITEHI (1 << 0)
#define BCM43xx_PIO_TXCTL_WRITELO (1 << 1)
#define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2)
#define BCM43xx_PIO_TXCTL_INIT (1 << 3)
#define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7)
#define BCM43xx_PIO_RXCTL_DATAAVAILABLE (1 << 0)
#define BCM43xx_PIO_RXCTL_READY (1 << 1)
/* PIO constants */
#define BCM43xx_PIO_MAXTXDEVQPACKETS 31
#define BCM43xx_PIO_TXQADJUST 80
/* PIO tuning knobs */
#define BCM43xx_PIO_MAXTXPACKETS 256
struct bcm43xx_pioqueue;
struct bcm43xx_xmitstatus;
struct bcm43xx_pio_txpacket {
struct bcm43xx_pioqueue *queue;
struct ieee80211_txb *txb;
struct list_head list;
u8 xmitted_frags;
u16 xmitted_octets;
};
#define pio_txpacket_getindex(packet) ((int)((packet) - (packet)->queue->__tx_packets_cache))
struct bcm43xx_pioqueue {
struct bcm43xx_private *bcm;
u16 mmio_base;
u8 tx_suspended:1;
/* Adjusted size of the device internal TX buffer. */
u16 tx_devq_size;
/* Used octets of the device internal TX buffer. */
u16 tx_devq_used;
/* Used packet slots in the device internal TX buffer. */
u8 tx_devq_packets;
/* Packets from the txfree list can
* be taken on incoming TX requests.
*/
struct list_head txfree;
/* Packets on the txqueue are queued,
* but not completely written to the chip, yet.
*/
struct list_head txqueue;
/* Packets on the txrunning queue are completely
* posted to the device. We are waiting for the txstatus.
*/
struct list_head txrunning;
/* Locking of the TX queues and the accounting. */
spinlock_t txlock;
struct work_struct txwork;
struct bcm43xx_pio_txpacket __tx_packets_cache[BCM43xx_PIO_MAXTXPACKETS];
};
int bcm43xx_pio_init(struct bcm43xx_private *bcm);
void bcm43xx_pio_free(struct bcm43xx_private *bcm);
int FASTCALL(bcm43xx_pio_transfer_txb(struct bcm43xx_private *bcm,
struct ieee80211_txb *txb));
void FASTCALL(bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status));
void FASTCALL(bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue));
#endif /* BCM43xx_PIO_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment